Rollup merge of #135865 - zachs18:maybe_report_similar_assoc_fn_more, r=compiler-errors
For E0223, suggest associated functions that are similar to the path, even if the base type has multiple inherent impl blocks. Currently, the "help: there is an associated function with a similar name `from_utf8`" suggestion for `String::from::utf8` is only given if `String` has exactly one inherent `impl` item. This PR makes the suggestion be emitted even if the base type has multiple inherent `impl` items. Example: ```rust struct Foo; impl Foo { fn bar_baz() {} } impl Foo {} // load-bearing fn main() { Foo::bar::baz; } ``` Nightly/stable output: ```rust error[E0223]: ambiguous associated type --> f.rs:7:5 | 7 | Foo::bar::baz; | ^^^^^^^^ | help: if there were a trait named `Example` with associated type `bar` implemented for `Foo`, you could use the fully-qualified path | 7 | <Foo as Example>::bar::baz; | ~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0223`. ``` Output with this PR, or without the load-bearing empty impl on nightly/stable: ```rust error[E0223]: ambiguous associated type --> f.rs:7:5 | 7 | Foo::bar::baz; | ^^^^^^^^ | help: there is an associated function with a similar name: `bar_baz` | 7 | Foo::bar_baz; | ~~~~~~~ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0223`. ``` Ideally, this suggestion would also work for non-ADT types like ~~`str::char::indices`~~ (edit: latest commit makes this work with primitives) or `<dyn Any>::downcast::mut_unchecked`, but that seemed to be a harder change. `@rustbot` label +A-diagnostics
This commit is contained in:
commit
efb8084672
6 changed files with 200 additions and 96 deletions
|
@ -9,6 +9,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::bug;
|
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::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
|
self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
|
||||||
|
@ -998,12 +999,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
)),
|
)),
|
||||||
..
|
..
|
||||||
}) = node
|
}) = node
|
||||||
&& let Some(adt_def) = qself_ty.ty_adt_def()
|
&& let Some(inherent_impls) = qself_ty
|
||||||
&& let [inherent_impl] = tcx.inherent_impls(adt_def.did())
|
.ty_adt_def()
|
||||||
&& let name = format!("{ident2}_{ident3}")
|
.map(|adt_def| tcx.inherent_impls(adt_def.did()))
|
||||||
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
|
.or_else(|| {
|
||||||
.associated_items(inherent_impl)
|
simplify_type(tcx, qself_ty, TreatParams::InstantiateWithInfer)
|
||||||
.filter_by_name_unhygienic(Symbol::intern(&name))
|
.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()
|
.next()
|
||||||
{
|
{
|
||||||
Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type")
|
Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type")
|
||||||
|
|
|
@ -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-106443-sugg-clone-for-bound.rs
|
||||||
ui/suggestions/issue-107860.rs
|
ui/suggestions/issue-107860.rs
|
||||||
ui/suggestions/issue-108470.rs
|
ui/suggestions/issue-108470.rs
|
||||||
ui/suggestions/issue-109195.rs
|
|
||||||
ui/suggestions/issue-109291.rs
|
ui/suggestions/issue-109291.rs
|
||||||
ui/suggestions/issue-109396.rs
|
ui/suggestions/issue-109396.rs
|
||||||
ui/suggestions/issue-109436.rs
|
ui/suggestions/issue-109436.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`
|
||||||
|
}
|
|
@ -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`.
|
|
@ -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`
|
|
||||||
}
|
|
|
@ -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`.
|
|
Loading…
Add table
Add a link
Reference in a new issue