about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-10-13 23:31:35 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-10-17 17:33:08 +0000
commit5cc9216ff3552ac1f6b545860bc25f25cf6551df (patch)
tree3c598760af9f70290795b5c2e36b7b5fefe5d9ef
parent93e62a260f9edb5813a73908120a43f1415f2c8c (diff)
downloadrust-5cc9216ff3552ac1f6b545860bc25f25cf6551df.tar.gz
rust-5cc9216ff3552ac1f6b545860bc25f25cf6551df.zip
Properly account for self ty in method disambiguation suggestion
Fix #116703.
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs9
-rw-r--r--tests/ui/methods/disambiguate-multiple-blanket-impl.rs27
-rw-r--r--tests/ui/methods/disambiguate-multiple-blanket-impl.stderr28
-rw-r--r--tests/ui/methods/disambiguate-multiple-impl.rs26
-rw-r--r--tests/ui/methods/disambiguate-multiple-impl.stderr28
5 files changed, 115 insertions, 3 deletions
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 8ea0280c5e9..56d7b94d493 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1322,7 +1322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let path = self.tcx.def_path_str(trait_ref.skip_binder().def_id);
 
                         let ty = match item.kind {
-                            ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
+                            ty::AssocKind::Const | ty::AssocKind::Type => impl_ty,
                             ty::AssocKind::Fn => self
                                 .tcx
                                 .fn_sig(item.def_id)
@@ -1340,6 +1340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             err,
                             path,
                             ty,
+                            impl_ty,
                             item.kind,
                             self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
                             sugg_span,
@@ -1376,6 +1377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             err,
                             path,
                             rcvr_ty,
+                            rcvr_ty,
                             item.kind,
                             self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
                             sugg_span,
@@ -3146,6 +3148,7 @@ fn print_disambiguation_help<'tcx>(
     err: &mut Diagnostic,
     trait_name: String,
     rcvr_ty: Ty<'_>,
+    self_ty: Ty<'_>,
     kind: ty::AssocKind,
     def_kind_descr: &'static str,
     span: Span,
@@ -3172,13 +3175,13 @@ fn print_disambiguation_help<'tcx>(
                 .join(", "),
         );
         let trait_name = if !fn_has_self_parameter {
-            format!("<{rcvr_ty} as {trait_name}>")
+            format!("<{self_ty} as {trait_name}>")
         } else {
             trait_name
         };
         (span, format!("{trait_name}::{item_name}{args}"))
     } else {
-        (span.with_hi(item_name.span.lo()), format!("<{rcvr_ty} as {trait_name}>::"))
+        (span.with_hi(item_name.span.lo()), format!("<{self_ty} as {trait_name}>::"))
     };
     err.span_suggestion_verbose(
         span,
diff --git a/tests/ui/methods/disambiguate-multiple-blanket-impl.rs b/tests/ui/methods/disambiguate-multiple-blanket-impl.rs
new file mode 100644
index 00000000000..39ac3389aab
--- /dev/null
+++ b/tests/ui/methods/disambiguate-multiple-blanket-impl.rs
@@ -0,0 +1,27 @@
+trait A {
+    fn foo(&self);
+}
+
+trait B {
+    fn foo(&self);
+}
+
+#[derive(Debug)]
+struct S;
+
+impl<T: std::fmt::Debug> A for T {
+    fn foo(&self) {} //~ NOTE candidate #1
+}
+
+impl<T: std::fmt::Debug> B for T {
+    fn foo(&self) {} //~ NOTE candidate #2
+}
+
+fn main() {
+    let s = S;
+    S::foo(&s); //~ ERROR multiple applicable items in scope
+    //~^ NOTE multiple `foo` found
+    //~| HELP disambiguate
+    //~| HELP disambiguate
+}
+
diff --git a/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr b/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
new file mode 100644
index 00000000000..dd0af051bb9
--- /dev/null
+++ b/tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
@@ -0,0 +1,28 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/disambiguate-multiple-blanket-impl.rs:22:8
+   |
+LL |     S::foo(&s);
+   |        ^^^ multiple `foo` found
+   |
+note: candidate #1 is defined in an impl of the trait `A` for the type `T`
+  --> $DIR/disambiguate-multiple-blanket-impl.rs:13:5
+   |
+LL |     fn foo(&self) {}
+   |     ^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl of the trait `B` for the type `T`
+  --> $DIR/disambiguate-multiple-blanket-impl.rs:17:5
+   |
+LL |     fn foo(&self) {}
+   |     ^^^^^^^^^^^^^
+help: disambiguate the method for candidate #1
+   |
+LL |     <T as A>::foo(&s);
+   |     ~~~~~~~~~~
+help: disambiguate the method for candidate #2
+   |
+LL |     <T as B>::foo(&s);
+   |     ~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/methods/disambiguate-multiple-impl.rs b/tests/ui/methods/disambiguate-multiple-impl.rs
new file mode 100644
index 00000000000..fa9942c745a
--- /dev/null
+++ b/tests/ui/methods/disambiguate-multiple-impl.rs
@@ -0,0 +1,26 @@
+trait A {
+    fn foo(&self);
+}
+
+trait B {
+    fn foo(&self);
+}
+
+struct S;
+
+impl A for S {
+    fn foo(&self) {} //~ NOTE candidate #1
+}
+
+impl B for S {
+    fn foo(&self) {} //~ NOTE candidate #2
+}
+
+fn main() {
+    let s = S;
+    S::foo(&s); //~ ERROR multiple applicable items in scope
+    //~^ NOTE multiple `foo` found
+    //~| HELP disambiguate
+    //~| HELP disambiguate
+}
+
diff --git a/tests/ui/methods/disambiguate-multiple-impl.stderr b/tests/ui/methods/disambiguate-multiple-impl.stderr
new file mode 100644
index 00000000000..b9fd10dba8d
--- /dev/null
+++ b/tests/ui/methods/disambiguate-multiple-impl.stderr
@@ -0,0 +1,28 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/disambiguate-multiple-impl.rs:21:8
+   |
+LL |     S::foo(&s);
+   |        ^^^ multiple `foo` found
+   |
+note: candidate #1 is defined in an impl of the trait `A` for the type `S`
+  --> $DIR/disambiguate-multiple-impl.rs:12:5
+   |
+LL |     fn foo(&self) {}
+   |     ^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl of the trait `B` for the type `S`
+  --> $DIR/disambiguate-multiple-impl.rs:16:5
+   |
+LL |     fn foo(&self) {}
+   |     ^^^^^^^^^^^^^
+help: disambiguate the method for candidate #1
+   |
+LL |     <S as A>::foo(&s);
+   |     ~~~~~~~~~~
+help: disambiguate the method for candidate #2
+   |
+LL |     <S as B>::foo(&s);
+   |     ~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.