about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-04-25 15:13:51 +0000
committerMichael Goulet <michael@errs.io>2025-04-30 18:07:52 +0000
commitf2930001aa6dd5f5056c69c96c1eaf4b31dfedd8 (patch)
tree03862966f26faf1d9d16b38bd00b845481c1a027
parent7188f453111502962326022740e2657fce0a6939 (diff)
downloadrust-f2930001aa6dd5f5056c69c96c1eaf4b31dfedd8.tar.gz
rust-f2930001aa6dd5f5056c69c96c1eaf4b31dfedd8.zip
Use select in projection lookup
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs42
-rw-r--r--tests/ui/associated-types/mismatch-two-relevant-impls.rs20
-rw-r--r--tests/ui/associated-types/mismatch-two-relevant-impls.stderr20
3 files changed, 62 insertions, 20 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index ab2aa0ae469..970160ba212 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -15,6 +15,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, LangItem, Node};
 use rustc_infer::infer::{InferOk, TypeTrace};
+use rustc_infer::traits::ImplSource;
 use rustc_infer::traits::solve::Goal;
 use rustc_middle::traits::SignatureMismatchData;
 use rustc_middle::traits::select::OverflowError;
@@ -48,8 +49,8 @@ use crate::infer::{self, InferCtxt, InferCtxtExt as _};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::{
     MismatchedProjectionTypes, NormalizeExt, Obligation, ObligationCause, ObligationCauseCode,
-    ObligationCtxt, Overflow, PredicateObligation, SelectionError, SignatureMismatch,
-    TraitDynIncompatible, elaborate,
+    ObligationCtxt, Overflow, PredicateObligation, SelectionContext, SelectionError,
+    SignatureMismatch, TraitDynIncompatible, elaborate, specialization_graph,
 };
 
 impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
@@ -1495,32 +1496,33 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 }
             }
 
-            let secondary_span = (|| {
+            let secondary_span = self.probe(|_| {
                 let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =
                     predicate.kind().skip_binder()
                 else {
                     return None;
                 };
 
-                let mut associated_items = vec![];
-                self.tcx.for_each_relevant_impl(
-                    self.tcx.trait_of_item(proj.projection_term.def_id)?,
-                    proj.projection_term.self_ty(),
-                    |impl_def_id| {
-                        associated_items.extend(
-                            self.tcx.associated_items(impl_def_id).in_definition_order().find(
-                                |assoc| {
-                                    assoc.trait_item_def_id == Some(proj.projection_term.def_id)
-                                },
-                            ),
-                        );
-                    },
-                );
+                let Ok(Some(ImplSource::UserDefined(impl_data))) = SelectionContext::new(self)
+                    .poly_select(&obligation.with(
+                        self.tcx,
+                        predicate.kind().rebind(proj.projection_term.trait_ref(self.tcx)),
+                    ))
+                else {
+                    return None;
+                };
 
-                let [associated_item]: &[ty::AssocItem] = &associated_items[..] else {
+                let Ok(node) =
+                    specialization_graph::assoc_def(self.tcx, impl_data.impl_def_id, proj.def_id())
+                else {
                     return None;
                 };
-                match self.tcx.hir_get_if_local(associated_item.def_id) {
+
+                if !node.is_final() {
+                    return None;
+                }
+
+                match self.tcx.hir_get_if_local(node.item.def_id) {
                     Some(
                         hir::Node::TraitItem(hir::TraitItem {
                             kind: hir::TraitItemKind::Type(_, Some(ty)),
@@ -1543,7 +1545,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     )),
                     _ => None,
                 }
-            })();
+            });
 
             self.note_type_err(
                 &mut diag,
diff --git a/tests/ui/associated-types/mismatch-two-relevant-impls.rs b/tests/ui/associated-types/mismatch-two-relevant-impls.rs
new file mode 100644
index 00000000000..58fd567c278
--- /dev/null
+++ b/tests/ui/associated-types/mismatch-two-relevant-impls.rs
@@ -0,0 +1,20 @@
+trait Tr {
+    type Assoc;
+}
+
+struct W<T>(T);
+
+impl Tr for W<i32> {
+    type Assoc = u32;
+}
+
+impl Tr for W<u32> {
+    type Assoc = i32;
+}
+
+fn needs_unit<T: Tr<Assoc = ()>>() {}
+
+fn main() {
+    needs_unit::<W<i32>>();
+    //~^ ERROR type mismatch resolving `<W<i32> as Tr>::Assoc == ()`
+}
diff --git a/tests/ui/associated-types/mismatch-two-relevant-impls.stderr b/tests/ui/associated-types/mismatch-two-relevant-impls.stderr
new file mode 100644
index 00000000000..2a1f3ef23ca
--- /dev/null
+++ b/tests/ui/associated-types/mismatch-two-relevant-impls.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<W<i32> as Tr>::Assoc == ()`
+  --> $DIR/mismatch-two-relevant-impls.rs:18:18
+   |
+LL |     needs_unit::<W<i32>>();
+   |                  ^^^^^^ type mismatch resolving `<W<i32> as Tr>::Assoc == ()`
+   |
+note: expected this to be `()`
+  --> $DIR/mismatch-two-relevant-impls.rs:8:18
+   |
+LL |     type Assoc = u32;
+   |                  ^^^
+note: required by a bound in `needs_unit`
+  --> $DIR/mismatch-two-relevant-impls.rs:15:21
+   |
+LL | fn needs_unit<T: Tr<Assoc = ()>>() {}
+   |                     ^^^^^^^^^^ required by this bound in `needs_unit`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.