Iām also not an expert, but Iām thinking about this idea of disambiguating implās the way you would disambiguate methods.
So, if you have crate some_trait providing SomeTrait, and crate some_struct providing SomeStruct, and then crates foo and bar both implement SomeTrait for SomeStruct, then you have to disambiguate between, letās call them foo::SomeTrait and bar::SomeTrait.
I guess the sticking point is when a crate thatās NOT foo or bar cares about SomeTrait. Such as the original crate, some_trait. In some_trait, you might have:
fn consumer <T: SomeTrait> (input: T) {ā¦}
And then in my crate, baz, which imports both foo and bar, I do:
some_trait::consumer (SomeStruct::default());
In order to monomorphize consumer, it has to know not just T = SomeStruct
, but T = SomeStruct with the SomeTrait impl from foo
. Well, letās assume I have a way to disambiguate that. I always prefer fooās impl, so whenever I call a generic function that uses SomeTrait, it should use the impl from foo. I guess that includes even if I call a generic method from bar ā after all, a generic method implemented in bar would have no reason to assume anything about the impl used for it.
Iāve been trying to think about counterintuitive cases that would arise from this, but itās surprisingly difficult. Hereās the worst Iāve come up with so far:
//in some_trait
trait SomeTrait {
type Associated: Eq;
fn get_associated (&self)->Associated;
}
ā¦
//In foo
impl SomeTrait for SomeStruct {type Associated = i64; ā¦}
ā¦
//in bar
impl SomeTrait for SomeStruct {type Associated = [i64; 2]; ā¦}
fn complex_operation_returning_associated (input: &SomeStruct)->SomeStruct::Associated {ā¦}
ā¦
//In baz
prefer impl SomeTrait for SomeStruct from foo;
fn do_something (input: &SomeStruct)->bool {
//compile error, mismatched types
input.get_associated() == foo::complex_operation_returning_associated(input)
}