From 3bf9eb0f7a1f2da9df2983aa8cf95a420130cada Mon Sep 17 00:00:00 2001 From: XIAO Tian Date: Sat, 30 May 2020 11:28:33 +0800 Subject: [PATCH 1/2] Add a test for wrong assoc type diagnostics --- src/test/ui/associated-types/issue-72806.rs | 20 +++++++++++++++++++ .../ui/associated-types/issue-72806.stderr | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/test/ui/associated-types/issue-72806.rs create mode 100644 src/test/ui/associated-types/issue-72806.stderr diff --git a/src/test/ui/associated-types/issue-72806.rs b/src/test/ui/associated-types/issue-72806.rs new file mode 100644 index 0000000000000..ae63781d568a1 --- /dev/null +++ b/src/test/ui/associated-types/issue-72806.rs @@ -0,0 +1,20 @@ +trait Bar { + type Ok; + type Sibling: Bar2; +} +trait Bar2 { + type Ok; +} + +struct Foo; +struct Foo2; + +impl Bar for Foo { //~ ERROR type mismatch resolving `::Ok == char` + type Ok = (); + type Sibling = Foo2; +} +impl Bar2 for Foo2 { + type Ok = u32; +} + +fn main() {} diff --git a/src/test/ui/associated-types/issue-72806.stderr b/src/test/ui/associated-types/issue-72806.stderr new file mode 100644 index 0000000000000..03a6565848dc3 --- /dev/null +++ b/src/test/ui/associated-types/issue-72806.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `::Ok == char` + --> $DIR/issue-72806.rs:12:6 + | +LL | impl Bar for Foo { + | ^^^ expected `u32`, found `char` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. From 1a68c8e8d957e8df19e5adced776879bbe3d5344 Mon Sep 17 00:00:00 2001 From: XIAO Tian Date: Sat, 30 May 2020 11:26:46 +0800 Subject: [PATCH 2/2] Fix associate type diagnostics --- src/librustc_trait_selection/traits/wf.rs | 31 +++++++++-------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs index 714ca7a30cff6..39c7528a63240 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/src/librustc_trait_selection/traits/wf.rs @@ -172,25 +172,18 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( }; match pred.kind() { ty::PredicateKind::Projection(proj) => { - // The obligation comes not from the current `impl` nor the `trait` being - // implemented, but rather from a "second order" obligation, like in - // `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs`. - let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); - if let Some(impl_item_span) = - items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span) - { - cause.span = impl_item_span; - } else { - let kind = &proj.ty().skip_binder().kind; - if let ty::Projection(projection_ty) = kind { - // This happens when an associated type has a projection coming from another - // associated type. See `traits-assoc-type-in-supertrait-bad.rs`. - let trait_assoc_item = tcx.associated_item(projection_ty.item_def_id); - if let Some(impl_item_span) = - items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span) - { - cause.span = impl_item_span; - } + // The obligation comes not from the current `impl` nor the `trait` being implemented, + // but rather from a "second order" obligation, where an associated type has a + // projection coming from another associated type. See + // `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and + // `traits-assoc-type-in-supertrait-bad.rs`. + let kind = &proj.ty().skip_binder().kind; + if let ty::Projection(projection_ty) = kind { + let trait_assoc_item = tcx.associated_item(projection_ty.item_def_id); + if let Some(impl_item_span) = + items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span) + { + cause.span = impl_item_span; } } }