Why can't I add a blanket impl on a trait with a type parameter?

前端 未结 2 1003
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-04 01:49

Consider these two traits:

pub trait Foo {
    fn new(arg: u32) -> Self;
}

pub trait Bar

: Foo { fn with_parameter(arg: u32, parameter: P) -&

2条回答
  •  暖寄归人
    2020-12-04 02:22

    I've broken down and extended Francis's explanation of why the code does not compile. I may not be the smartest kid on the block, but it took me way too long to understand his concise reasoning.

    Let's create Baz, which implements Bar in 2 variants: i32 and String:

    struct Baz;
    
    impl Bar for Baz { /* ... */ }
    
    impl Bar for Baz { /* ... */ }
    

    Type dependency graph after blanket impl takes effect:

               -> trait Bar    -> trait Foo (with i32 baked-in)
    struct Baz
               -> trait Bar -> trait Foo (with String baked-in)
    

    We end up with 2 different implementations of Foo: with baked-in i32 and with baked-in String. When we write ::new(), compiler can't tell which version of Foo we mean; they are indistinguishable.

    The rule of a thumb is that trait A can have blanket implementation for trait B only if trait A is generic over all generic parameters of trait B.

提交回复
热议问题