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

The problem is that a single type could implement Bar<P> for multiple values of P. If you had a struct Baz that implemented Bar<i32> and Bar<String>, which type should Foo::new use for P?

The only solution is to ensure that a single type cannot implement Bar more than once (if that’s not what you want, then you have a flaw in your design!). To do so, we must replace the P type parameter with an associated type.

pub trait Bar: Foo {
    type Parameter;

    fn with_parameter(arg: u32, parameter: Self::Parameter) -> Self;
}

impl<T> Foo for T
where
    T: Bar,
    T::Parameter: Default,
{
    fn new(arg: u32) -> Self {
        Self::with_parameter(arg, T::Parameter::default())
    }
}

An implementation of Bar would look like this:

struct Baz;

impl Bar for Baz {
    type Parameter = i32;

    fn with_parameter(arg: u32, parameter: Self::Parameter) -> Self {
        unimplemented!()
    }
}

See also:

Leave a Comment