about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs20
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs51
-rw-r--r--tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.stderr135
-rw-r--r--tests/ui/suggestions/issue-109195.rs20
-rw-r--r--tests/ui/suggestions/issue-109195.stderr69
6 files changed, 200 insertions, 96 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 5d751a25080..36b214b6ae7 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -9,6 +9,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
+use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
 use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
 use rustc_middle::ty::{
     self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
@@ -998,12 +999,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     )),
                 ..
             }) = node
-            && let Some(adt_def) = qself_ty.ty_adt_def()
-            && let [inherent_impl] = tcx.inherent_impls(adt_def.did())
-            && let name = format!("{ident2}_{ident3}")
-            && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
-                .associated_items(inherent_impl)
-                .filter_by_name_unhygienic(Symbol::intern(&name))
+            && let Some(inherent_impls) = qself_ty
+                .ty_adt_def()
+                .map(|adt_def| tcx.inherent_impls(adt_def.did()))
+                .or_else(|| {
+                    simplify_type(tcx, qself_ty, TreatParams::InstantiateWithInfer)
+                        .map(|simple_ty| tcx.incoherent_impls(simple_ty))
+                })
+            && let name = Symbol::intern(&format!("{ident2}_{ident3}"))
+            && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = inherent_impls
+                .iter()
+                .flat_map(|inherent_impl| {
+                    tcx.associated_items(inherent_impl).filter_by_name_unhygienic(name)
+                })
                 .next()
         {
             Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type")
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index de3380502bf..5878cce5ffb 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -3857,7 +3857,6 @@ ui/suggestions/issue-106443-sugg-clone-for-arg.rs
 ui/suggestions/issue-106443-sugg-clone-for-bound.rs
 ui/suggestions/issue-107860.rs
 ui/suggestions/issue-108470.rs
-ui/suggestions/issue-109195.rs
 ui/suggestions/issue-109291.rs
 ui/suggestions/issue-109396.rs
 ui/suggestions/issue-109436.rs
diff --git a/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs b/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs
new file mode 100644
index 00000000000..a9c2c20ef37
--- /dev/null
+++ b/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.rs
@@ -0,0 +1,51 @@
+// https://github.com/rust-lang/rust/issues/109195
+struct Foo;
+
+impl Foo {
+    fn bar_baz() {}
+}
+
+impl Foo {
+    fn bar_quux() {}
+}
+
+fn main() {
+    String::from::utf8;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `from_utf8`
+    String::from::utf8();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `from_utf8`
+    String::from::utf16();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `from_utf16`
+    String::from::method_that_doesnt_exist();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `from`
+    str::into::string();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `into_string`
+    str::char::indices();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `char_indices`
+    Foo::bar::baz;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `bar_baz`
+    Foo::bar::quux;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `bar_quux`
+    Foo::bar::fizz;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `bar`
+    i32::wrapping::add;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `wrapping_add`
+    i32::wrapping::method_that_doesnt_exist;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `wrapping`
+
+    // this one ideally should suggest `downcast_mut_unchecked`
+    <dyn std::any::Any>::downcast::mut_unchecked;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `downcast`
+}
diff --git a/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.stderr b/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.stderr
new file mode 100644
index 00000000000..5863aa28f41
--- /dev/null
+++ b/tests/ui/suggestions/ambiguous-assoc-type-path-suggest-similar-item.stderr
@@ -0,0 +1,135 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:13:5
+   |
+LL |     String::from::utf8;
+   |     ^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `from_utf8`
+   |
+LL |     String::from_utf8;
+   |             ~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:16:5
+   |
+LL |     String::from::utf8();
+   |     ^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `from_utf8`
+   |
+LL |     String::from_utf8();
+   |             ~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:19:5
+   |
+LL |     String::from::utf16();
+   |     ^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `from_utf16`
+   |
+LL |     String::from_utf16();
+   |             ~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:22:5
+   |
+LL |     String::from::method_that_doesnt_exist();
+   |     ^^^^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `from` implemented for `String`, you could use the fully-qualified path
+   |
+LL |     <String as Example>::from::method_that_doesnt_exist();
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:25:5
+   |
+LL |     str::into::string();
+   |     ^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `into_string`
+   |
+LL |     str::into_string();
+   |          ~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:28:5
+   |
+LL |     str::char::indices();
+   |     ^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `char_indices`
+   |
+LL |     str::char_indices();
+   |          ~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:31:5
+   |
+LL |     Foo::bar::baz;
+   |     ^^^^^^^^
+   |
+help: there is an associated function with a similar name: `bar_baz`
+   |
+LL |     Foo::bar_baz;
+   |          ~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:34:5
+   |
+LL |     Foo::bar::quux;
+   |     ^^^^^^^^
+   |
+help: there is an associated function with a similar name: `bar_quux`
+   |
+LL |     Foo::bar_quux;
+   |          ~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:37:5
+   |
+LL |     Foo::bar::fizz;
+   |     ^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `bar` implemented for `Foo`, you could use the fully-qualified path
+   |
+LL |     <Foo as Example>::bar::fizz;
+   |     ~~~~~~~~~~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:40:5
+   |
+LL |     i32::wrapping::add;
+   |     ^^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `wrapping_add`
+   |
+LL |     i32::wrapping_add;
+   |          ~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:43:5
+   |
+LL |     i32::wrapping::method_that_doesnt_exist;
+   |     ^^^^^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `wrapping` implemented for `i32`, you could use the fully-qualified path
+   |
+LL |     <i32 as Example>::wrapping::method_that_doesnt_exist;
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:48:5
+   |
+LL |     <dyn std::any::Any>::downcast::mut_unchecked;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `downcast` implemented for `(dyn Any + 'static)`, you could use the fully-qualified path
+   |
+LL |     <(dyn Any + 'static) as Example>::downcast::mut_unchecked;
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/suggestions/issue-109195.rs b/tests/ui/suggestions/issue-109195.rs
deleted file mode 100644
index cc499b0d776..00000000000
--- a/tests/ui/suggestions/issue-109195.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-fn main() {
-    String::from::utf8;
-    //~^ ERROR ambiguous associated type [E0223]
-    //~| HELP there is an associated function with a similar name: `from_utf8`
-    String::from::utf8();
-    //~^ ERROR ambiguous associated type [E0223]
-    //~| HELP there is an associated function with a similar name: `from_utf8`
-    String::from::utf16();
-    //~^ ERROR ambiguous associated type [E0223]
-    //~| HELP there is an associated function with a similar name: `from_utf16`
-    String::from::method_that_doesnt_exist();
-    //~^ ERROR ambiguous associated type [E0223]
-    //~| HELP if there were a trait named `Example` with associated type `from`
-    str::from::utf8();
-    //~^ ERROR ambiguous associated type [E0223]
-    //~| HELP if there were a trait named `Example` with associated type `from`
-    str::from::utf8_mut();
-    //~^ ERROR ambiguous associated type [E0223]
-    //~| HELP if there were a trait named `Example` with associated type `from`
-}
diff --git a/tests/ui/suggestions/issue-109195.stderr b/tests/ui/suggestions/issue-109195.stderr
deleted file mode 100644
index 10cf9cfd28c..00000000000
--- a/tests/ui/suggestions/issue-109195.stderr
+++ /dev/null
@@ -1,69 +0,0 @@
-error[E0223]: ambiguous associated type
-  --> $DIR/issue-109195.rs:2:5
-   |
-LL |     String::from::utf8;
-   |     ^^^^^^^^^^^^
-   |
-help: there is an associated function with a similar name: `from_utf8`
-   |
-LL |     String::from_utf8;
-   |             ~~~~~~~~~
-
-error[E0223]: ambiguous associated type
-  --> $DIR/issue-109195.rs:5:5
-   |
-LL |     String::from::utf8();
-   |     ^^^^^^^^^^^^
-   |
-help: there is an associated function with a similar name: `from_utf8`
-   |
-LL |     String::from_utf8();
-   |             ~~~~~~~~~
-
-error[E0223]: ambiguous associated type
-  --> $DIR/issue-109195.rs:8:5
-   |
-LL |     String::from::utf16();
-   |     ^^^^^^^^^^^^
-   |
-help: there is an associated function with a similar name: `from_utf16`
-   |
-LL |     String::from_utf16();
-   |             ~~~~~~~~~~
-
-error[E0223]: ambiguous associated type
-  --> $DIR/issue-109195.rs:11:5
-   |
-LL |     String::from::method_that_doesnt_exist();
-   |     ^^^^^^^^^^^^
-   |
-help: if there were a trait named `Example` with associated type `from` implemented for `String`, you could use the fully-qualified path
-   |
-LL |     <String as Example>::from::method_that_doesnt_exist();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error[E0223]: ambiguous associated type
-  --> $DIR/issue-109195.rs:14:5
-   |
-LL |     str::from::utf8();
-   |     ^^^^^^^^^
-   |
-help: if there were a trait named `Example` with associated type `from` implemented for `str`, you could use the fully-qualified path
-   |
-LL |     <str as Example>::from::utf8();
-   |     ~~~~~~~~~~~~~~~~~~~~~~
-
-error[E0223]: ambiguous associated type
-  --> $DIR/issue-109195.rs:17:5
-   |
-LL |     str::from::utf8_mut();
-   |     ^^^^^^^^^
-   |
-help: if there were a trait named `Example` with associated type `from` implemented for `str`, you could use the fully-qualified path
-   |
-LL |     <str as Example>::from::utf8_mut();
-   |     ~~~~~~~~~~~~~~~~~~~~~~
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0223`.