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 5d751a250805f..36b214b6ae734 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 de3380502bfcd..5878cce5ffbdd 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 0000000000000..a9c2c20ef374a --- /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` + ::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 0000000000000..5863aa28f41f3 --- /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 | ::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 | ::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 | ::wrapping::method_that_doesnt_exist; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0223]: ambiguous associated type + --> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:48:5 + | +LL | ::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 cc499b0d77618..0000000000000 --- 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 10cf9cfd28ca7..0000000000000 --- 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 | ::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 | ::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 | ::from::utf8_mut(); - | ~~~~~~~~~~~~~~~~~~~~~~ - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0223`.