Benjie
Benjie

Reputation: 131

Is there a way to provide a derived implementation for traits that have a specific associated type?

I'm trying to write a blanket implementation of a trait for types that are another trait with a specific associated type. That is, it is fully permissible to do this:

use std::{marker::PhantomData, any::type_name};
trait TraitA {
    type Associated;
    fn a_method(&self) {
        println!("Hello from TraitA ({})",type_name::<Self::Associated>());
    }
}

trait TraitB {
    fn b_method(&self) {
        println!("Hello from TraitB")
    }
}

struct MyType<T> {
    member: PhantomData<T>
}

impl<T> TraitA for MyType<T> {
    type Associated = T;
}

/*
impl<T> TraitB for T
where T: TraitA<Associated = i16> {}
*/

impl<T> TraitB for T
where T: TraitA<Associated = i8> {}

fn main() {
    let my_var: MyType<i8> = MyType{member: PhantomData::default()};
    my_var.a_method();
    my_var.b_method();
}

This will compile, and will print

Hello from TraitA (i8)
Hello from TraitB

However, if I uncomment the impl for the i16 associated type, this results in the compile time error: error[E0119]: conflicting implementations of trait `TraitB

I don't understand why this is not permitted, given that there can only ever be one implementation of a trait with an associated type.

In other words, because this is a compile time error

impl<T> TraitA for MyType<T> {
    type Associated = i8;
}

impl<T> TraitA for MyType<T>
    type Associated = i16;
}

shouldn't it be the case that the above implementations are allowed? Is there a way to accomplish this with associated types?

Perhaps this does not work because the compiler is unable to determine that i8 and i16 are distinct types, and thus cannot tell that the two implementations do not overlap?

Note that in my use case, TraitA is not dyn compatible, so the answer in How to generate instance of trait for another trait is not relevant. (also, it would be better to use monomorphization instead of dynamic dispatch)

Upvotes: 0

Views: 29

Answers (0)

Related Questions