Skip to content

Commit

Permalink
Rollup merge of #72807 - xiaotianrandom:fix-assoc-type-diagnostics, r…
Browse files Browse the repository at this point in the history
…=estebank

Avoid setting wrong obligation cause span of associated type mismatch

Removes code that sets wrong obligation cause span of associated type mismatch. See the linked issue for details.

Closes #72806.
  • Loading branch information
Dylan-DPC authored May 31, 2020
2 parents 6cd9a67 + 1a68c8e commit 8e83a7e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
31 changes: 12 additions & 19 deletions src/librustc_trait_selection/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/test/ui/associated-types/issue-72806.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
trait Bar {
type Ok;
type Sibling: Bar2<Ok=char>;
}
trait Bar2 {
type Ok;
}

struct Foo;
struct Foo2;

impl Bar for Foo { //~ ERROR type mismatch resolving `<Foo2 as Bar2>::Ok == char`
type Ok = ();
type Sibling = Foo2;
}
impl Bar2 for Foo2 {
type Ok = u32;
}

fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/associated-types/issue-72806.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0271]: type mismatch resolving `<Foo2 as Bar2>::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`.

0 comments on commit 8e83a7e

Please sign in to comment.