Rollup merge of #72807 - xiaotianrandom:fix-assoc-type-diagnostics, r=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.
This commit is contained in:
Dylan DPC 2020-05-31 21:30:01 +02:00 committed by GitHub
commit 8e83a7e126
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 19 deletions

View file

@ -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;
}
}
}

View file

@ -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() {}

View file

@ -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`.