about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-14 11:20:25 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-11-15 11:26:17 +0000
commite2fbd01ac3305fd9bfb5ee4f76c42f06df4e1f10 (patch)
tree2112fff6107a754b1bdaa493e781d17a1d19422d
parentd06aac178358509cd7f416285e920f67bea1d64b (diff)
downloadrust-e2fbd01ac3305fd9bfb5ee4f76c42f06df4e1f10.tar.gz
rust-e2fbd01ac3305fd9bfb5ee4f76c42f06df4e1f10.zip
Compare picks via `Self` type and associated item id
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs26
2 files changed, 28 insertions, 2 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 1577eb666c8..3f390cba3e7 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -209,7 +209,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     call_expr,
                     ProbeScope::TraitsInScope,
                 ) {
-                    Ok(ref new_pick) if new_pick.self_ty != pick.self_ty => {
+                    Ok(ref new_pick) if pick.differs_from(new_pick) => {
                         needs_mut = true;
                     }
                     _ => {}
@@ -220,7 +220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut candidates =
                 match self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::AllTraits) {
                     // If we find a different result the caller probably forgot to import a trait.
-                    Ok(ref new_pick) if new_pick.self_ty != pick.self_ty => {
+                    Ok(ref new_pick) if pick.differs_from(new_pick) => {
                         vec![new_pick.item.container_id(self.tcx)]
                     }
                     Err(Ambiguity(ref sources)) => sources
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 6d46be40e62..46a76085189 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -17,6 +17,7 @@ use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
 use rustc_middle::middle::stability;
 use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
+use rustc_middle::ty::AssocItem;
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
@@ -1332,6 +1333,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
 impl<'tcx> Pick<'tcx> {
     /// In case there were unstable name collisions, emit them as a lint.
+    /// Checks whether two picks do not refer to the same trait item for the same `Self` type.
+    /// Only useful for comparisons of picks in order to improve diagnostics.
+    /// Do not use for type checking.
+    pub fn differs_from(&self, other: &Self) -> bool {
+        let Self {
+            item:
+                AssocItem {
+                    def_id,
+                    name: _,
+                    kind: _,
+                    container: _,
+                    trait_item_def_id: _,
+                    fn_has_self_parameter: _,
+                },
+            kind: _,
+            import_ids: _,
+            autoderefs: _,
+            autoref_or_ptr_adjustment: _,
+            self_ty,
+            unstable_candidates: _,
+        } = *self;
+        self_ty != other.self_ty || def_id != other.item.def_id
+    }
+
+    /// In case there were unstable name collisions, emit them as a lint.
     pub fn maybe_emit_unstable_name_collision_hint(
         &self,
         tcx: TyCtxt<'tcx>,