Description
Hello!
Given the following definitions (minimized from my actual use case):
trait DeviceIdContext {
type DeviceId;
}
trait BindingsContext<E> {}
trait EventContext<E> {
type OtherEventRepr;
}
trait CoreContext<BC>: DeviceIdContext + EventContext<Self::DeviceId> {}
struct Foo<D> {
d: D,
}
I'd like to be able to write the following implementation:
impl<D> Foo<D> {
fn foo<BC, CC>(self, _core_ctx: CC, _bindings_ctx: BC)
where
BC: BindingsContext<CC::OtherEventRepr>,
CC: CoreContext<BC, DeviceId = D> {}
}
Compilation fails with error:
CC: EventContext<D>
is not satisfied
However, that's incorrect. CC must implement EventContext. I've bounded its associated type DeviceId
to equal D. Along with the compilation error, comes the suggestion to add an explicit EventContext<D>
bound. That would look like the following:
impl<D> Foo<D> {
fn foo<BC, CC>(self, _core_ctx: CC, _bindings_ctx: BC)
where
BC: BindingsContext<CC::OtherEventRepr>,
CC: CoreContext<BC, DeviceId = D> + EventContext<D> {}
}
That still fails to compile, this time for a different reason:
ambiguous associated type
OtherEventRepr
in bounds ofCC
| ambiguousOtherEventRepr
fromEventContext<D>
| ambiguousOtherEventRepr
fromEventContext<<CC as DeviceIdContext>::DeviceId>
Interestingly, If I rework this implementation to be a free function, everything compiles:
fn foo<
BC: BindingsContext<CC::OtherEventRepr>,
CC: CoreContext<BC>
>(core_ctx: CC, bindings_ctx: BC, foo: Foo<CC::DeviceId>) {}
It seems to me that the DeviceId = D
bound I've written isn't able to be reasoned about properly in examples 1 & 2. Checkout this Rust Playground with all the examples from above: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=91049b46781fb054e583994d7dde5966
I observe this issue on Stable, Beta & Nightly.