Description
Bug
The following case (Playground) is slightly modifed based on that in #57663.
trait Bar {
type Ok;
type Sibling: Bar2<Ok=char>; // Here is modified, not using Self::Ok anymore
}
trait Bar2 {
type Ok;
}
struct Foo;
struct Foo2;
impl Bar for Foo {
type Ok = ();
type Sibling = Foo2;
}
impl Bar2 for Foo2 {
type Ok = u32;
}
fn main() {}
Error:
error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == char`
--> src/main.rs:13:15
|
13 | type Ok = ();
| ^^ expected `u32`, found `char`
This is wrong. It points to <Foo as Bar>::Ok
, which is not related to the error. <Foo as Bar>::Ok
just happens to have the same identifier as the mismatched associated type Bar2::Ok
. If I change the identifier in this line to something else (Playground), the error changes to the following. It is still not clear, but at least not that wrong.
error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == char`
--> src/main.rs:12:6
|
12 | impl Bar for Foo {
| ^^^ expected `u32`, found `char`
Cause
This is introduced by the PR #65288. The PR tries to make compile errors of associated type mismatch more informative. For an obligation related to a ty::ProjectionPredicate
, the PR (these lines) iterates over associated types in the current impl
(impl Bar for Foo
in this case) and looks for one having the same identifier as the projected item (Bar2::Ok
in this case). This is wrong and leads to the bug above. It just happens to work for the case in #57663, because in that case Bar
requires type Sibling: Bar2<Ok=Self::Ok>
and the two associated types have the same name Ok
.
PR #69793 refactors this code, adding a new branch (here) to look for ProjectionPredicate::ty
instead (char
in this case, not an associated type). This would work correctly for both this case and #57633. But this PR does not remove the old logic.
PR
I tried to delete the wrong branch and confirmed that all test cases passed as before. I will create a PR for that change shortly.