about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs46
-rw-r--r--tests/ui/specialization/min_specialization/issue-79224.stderr4
-rw-r--r--tests/ui/traits/issue-91594.stderr4
4 files changed, 38 insertions, 22 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index d1f4dbc8d84..ca45e16d9d9 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1254,7 +1254,11 @@ fn check_impl<'tcx>(
                 // therefore don't need to be WF (the trait's `Self: Trait` predicate
                 // won't hold).
                 let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
-                let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
+                let trait_ref = wfcx.normalize(
+                    ast_trait_ref.path.span,
+                    Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
+                    trait_ref,
+                );
                 let trait_pred = ty::TraitPredicate {
                     trait_ref,
                     constness: match constness {
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 4f9d5826583..2dbfc1bc9a2 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -114,34 +114,46 @@ fn diagnostic_hir_wf_check<'tcx>(
     // Get the starting `hir::Ty` using our `WellFormedLoc`.
     // We will walk 'into' this type to try to find
     // a more precise span for our predicate.
-    let ty = match loc {
+    let tys = match loc {
         WellFormedLoc::Ty(_) => match hir.get(hir_id) {
             hir::Node::ImplItem(item) => match item.kind {
-                hir::ImplItemKind::Type(ty) => Some(ty),
-                hir::ImplItemKind::Const(ty, _) => Some(ty),
+                hir::ImplItemKind::Type(ty) => vec![ty],
+                hir::ImplItemKind::Const(ty, _) => vec![ty],
                 ref item => bug!("Unexpected ImplItem {:?}", item),
             },
             hir::Node::TraitItem(item) => match item.kind {
-                hir::TraitItemKind::Type(_, ty) => ty,
-                hir::TraitItemKind::Const(ty, _) => Some(ty),
+                hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(),
+                hir::TraitItemKind::Const(ty, _) => vec![ty],
                 ref item => bug!("Unexpected TraitItem {:?}", item),
             },
             hir::Node::Item(item) => match item.kind {
-                hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
-                hir::ItemKind::Impl(ref impl_) => {
-                    assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
-                    Some(impl_.self_ty)
-                }
+                hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
+                hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait {
+                    Some(t) => t
+                        .path
+                        .segments
+                        .last()
+                        .iter()
+                        .flat_map(|seg| seg.args().args)
+                        .filter_map(|arg| {
+                            if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None }
+                        })
+                        .chain([impl_.self_ty])
+                        .collect(),
+                    None => {
+                        vec![impl_.self_ty]
+                    }
+                },
                 ref item => bug!("Unexpected item {:?}", item),
             },
-            hir::Node::Field(field) => Some(field.ty),
+            hir::Node::Field(field) => vec![field.ty],
             hir::Node::ForeignItem(ForeignItem {
                 kind: ForeignItemKind::Static(ty, _), ..
-            }) => Some(*ty),
+            }) => vec![*ty],
             hir::Node::GenericParam(hir::GenericParam {
                 kind: hir::GenericParamKind::Type { default: Some(ty), .. },
                 ..
-            }) => Some(*ty),
+            }) => vec![*ty],
             ref node => bug!("Unexpected node {:?}", node),
         },
         WellFormedLoc::Param { function: _, param_idx } => {
@@ -149,16 +161,16 @@ fn diagnostic_hir_wf_check<'tcx>(
             // Get return type
             if param_idx as usize == fn_decl.inputs.len() {
                 match fn_decl.output {
-                    hir::FnRetTy::Return(ty) => Some(ty),
+                    hir::FnRetTy::Return(ty) => vec![ty],
                     // The unit type `()` is always well-formed
-                    hir::FnRetTy::DefaultReturn(_span) => None,
+                    hir::FnRetTy::DefaultReturn(_span) => vec![],
                 }
             } else {
-                Some(&fn_decl.inputs[param_idx as usize])
+                vec![&fn_decl.inputs[param_idx as usize]]
             }
         }
     };
-    if let Some(ty) = ty {
+    for ty in tys {
         visitor.visit_ty(ty);
     }
     visitor.cause
diff --git a/tests/ui/specialization/min_specialization/issue-79224.stderr b/tests/ui/specialization/min_specialization/issue-79224.stderr
index be6f04ae62a..505baa23ca3 100644
--- a/tests/ui/specialization/min_specialization/issue-79224.stderr
+++ b/tests/ui/specialization/min_specialization/issue-79224.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:18:17
+  --> $DIR/issue-79224.rs:18:29
    |
 LL | impl<B: ?Sized> Display for Cow<'_, B> {
-   |                 ^^^^^^^ the trait `Clone` is not implemented for `B`
+   |                             ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
    |
    = note: required for `B` to implement `ToOwned`
 help: consider further restricting this bound
diff --git a/tests/ui/traits/issue-91594.stderr b/tests/ui/traits/issue-91594.stderr
index 6b314fa586d..85d903fadd1 100644
--- a/tests/ui/traits/issue-91594.stderr
+++ b/tests/ui/traits/issue-91594.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied
-  --> $DIR/issue-91594.rs:10:6
+  --> $DIR/issue-91594.rs:10:19
    |
 LL | impl HasComponent<<Foo as Component<Foo>>::Interface> for Foo {}
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo`
    |
    = help: the trait `HasComponent<<Foo as Component<Foo>>::Interface>` is implemented for `Foo`
 note: required for `Foo` to implement `Component<Foo>`