Compiler bug? Two trait bounds that should be independent seem to get confused
⚓ Rust 📅 2026-03-31 👤 surdeus 👁️ 7This is the best MRE I could come up with:
struct A;
struct B;
impl From<B> for A {
fn from(_: B) -> A {
A
}
}
trait V {
type E;
}
trait W {
type E;
}
struct X;
impl W for X {
type E = B;
}
fn inner<T>(_: T)
where
T: W,
A: From<<T as W>::E>,
{
}
fn outer<T>(_: T)
where
T: V,
A: From<<T as V>::E>,
{
inner(X);
}
This results in a compile-time error:
error[E0271]: type mismatch resolving `<X as W>::E == <T as V>::E`
--> src/lib.rs:36:5
|
36 | inner(X);
| ^^^^^^^^ type mismatch resolving `<X as W>::E == <T as V>::E`
|
note: expected this to be `<T as V>::E`
--> src/lib.rs:21:14
|
21 | type E = B;
| ^
= note: expected associated type `<T as V>::E`
found struct `B`
help: consider constraining the associated type `<T as V>::E` to `B`
|
33 | T: V<E = B>,
| +++++++
For more information about this error, try `rustc --explain E0271`.
It seems the compiler concludes that since A is bounded by From<T> on both functions, and one calls the other, that the two Ts must be the same, but this is false. There are two ways to make this compile:
- Remove the
A: From<<T as V>::E>bound fromouter. - Change the bound to
A: From<<T as V>::E> + From<<X as W>::E>, even though the additional bound shouldn't be required. - Transform one of the bounds to the equivalent
Intobound.
The fact that the first option allows the code to compile shows that the two Ts in From<T> are in fact totally independent -- there's just something about this specific pattern where the compiler seems to get confused and conclude they must be the same type.
Is there something I'm missing here or is this a bug? (Honestly, I have a strong suspicion I've seen this before and it was a bug, but if so then I can't come up with the search terms to find it again.)
In my real code, option 1 doesn't work since I need that bound, but option 2 is awkward because the W trait is private and the function is public.
3 posts - 2 participants
🏷️ Rust_feed