Skip to content
/ rust Public
forked from rust-lang/rust

Commit efb8084

Browse files
authored
Rollup merge of rust-lang#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
2 parents 40e2858 + 2c58212 commit efb8084

File tree

6 files changed

+200
-96
lines changed

6 files changed

+200
-96
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_hir as hir;
99
use rustc_hir::def::{DefKind, Res};
1010
use rustc_hir::def_id::DefId;
1111
use rustc_middle::bug;
12+
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
1213
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
1314
use rustc_middle::ty::{
1415
self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt,
@@ -998,12 +999,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
998999
)),
9991000
..
10001001
}) = node
1001-
&& let Some(adt_def) = qself_ty.ty_adt_def()
1002-
&& let [inherent_impl] = tcx.inherent_impls(adt_def.did())
1003-
&& let name = format!("{ident2}_{ident3}")
1004-
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
1005-
.associated_items(inherent_impl)
1006-
.filter_by_name_unhygienic(Symbol::intern(&name))
1002+
&& let Some(inherent_impls) = qself_ty
1003+
.ty_adt_def()
1004+
.map(|adt_def| tcx.inherent_impls(adt_def.did()))
1005+
.or_else(|| {
1006+
simplify_type(tcx, qself_ty, TreatParams::InstantiateWithInfer)
1007+
.map(|simple_ty| tcx.incoherent_impls(simple_ty))
1008+
})
1009+
&& let name = Symbol::intern(&format!("{ident2}_{ident3}"))
1010+
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = inherent_impls
1011+
.iter()
1012+
.flat_map(|inherent_impl| {
1013+
tcx.associated_items(inherent_impl).filter_by_name_unhygienic(name)
1014+
})
10071015
.next()
10081016
{
10091017
Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type")

src/tools/tidy/src/issues.txt

-1
Original file line numberDiff line numberDiff line change
@@ -3857,7 +3857,6 @@ ui/suggestions/issue-106443-sugg-clone-for-arg.rs
38573857
ui/suggestions/issue-106443-sugg-clone-for-bound.rs
38583858
ui/suggestions/issue-107860.rs
38593859
ui/suggestions/issue-108470.rs
3860-
ui/suggestions/issue-109195.rs
38613860
ui/suggestions/issue-109291.rs
38623861
ui/suggestions/issue-109396.rs
38633862
ui/suggestions/issue-109436.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// https://github.com/rust-lang/rust/issues/109195
2+
struct Foo;
3+
4+
impl Foo {
5+
fn bar_baz() {}
6+
}
7+
8+
impl Foo {
9+
fn bar_quux() {}
10+
}
11+
12+
fn main() {
13+
String::from::utf8;
14+
//~^ ERROR ambiguous associated type [E0223]
15+
//~| HELP there is an associated function with a similar name: `from_utf8`
16+
String::from::utf8();
17+
//~^ ERROR ambiguous associated type [E0223]
18+
//~| HELP there is an associated function with a similar name: `from_utf8`
19+
String::from::utf16();
20+
//~^ ERROR ambiguous associated type [E0223]
21+
//~| HELP there is an associated function with a similar name: `from_utf16`
22+
String::from::method_that_doesnt_exist();
23+
//~^ ERROR ambiguous associated type [E0223]
24+
//~| HELP if there were a trait named `Example` with associated type `from`
25+
str::into::string();
26+
//~^ ERROR ambiguous associated type [E0223]
27+
//~| HELP there is an associated function with a similar name: `into_string`
28+
str::char::indices();
29+
//~^ ERROR ambiguous associated type [E0223]
30+
//~| HELP there is an associated function with a similar name: `char_indices`
31+
Foo::bar::baz;
32+
//~^ ERROR ambiguous associated type [E0223]
33+
//~| HELP there is an associated function with a similar name: `bar_baz`
34+
Foo::bar::quux;
35+
//~^ ERROR ambiguous associated type [E0223]
36+
//~| HELP there is an associated function with a similar name: `bar_quux`
37+
Foo::bar::fizz;
38+
//~^ ERROR ambiguous associated type [E0223]
39+
//~| HELP if there were a trait named `Example` with associated type `bar`
40+
i32::wrapping::add;
41+
//~^ ERROR ambiguous associated type [E0223]
42+
//~| HELP there is an associated function with a similar name: `wrapping_add`
43+
i32::wrapping::method_that_doesnt_exist;
44+
//~^ ERROR ambiguous associated type [E0223]
45+
//~| HELP if there were a trait named `Example` with associated type `wrapping`
46+
47+
// this one ideally should suggest `downcast_mut_unchecked`
48+
<dyn std::any::Any>::downcast::mut_unchecked;
49+
//~^ ERROR ambiguous associated type [E0223]
50+
//~| HELP if there were a trait named `Example` with associated type `downcast`
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
error[E0223]: ambiguous associated type
2+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:13:5
3+
|
4+
LL | String::from::utf8;
5+
| ^^^^^^^^^^^^
6+
|
7+
help: there is an associated function with a similar name: `from_utf8`
8+
|
9+
LL | String::from_utf8;
10+
| ~~~~~~~~~
11+
12+
error[E0223]: ambiguous associated type
13+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:16:5
14+
|
15+
LL | String::from::utf8();
16+
| ^^^^^^^^^^^^
17+
|
18+
help: there is an associated function with a similar name: `from_utf8`
19+
|
20+
LL | String::from_utf8();
21+
| ~~~~~~~~~
22+
23+
error[E0223]: ambiguous associated type
24+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:19:5
25+
|
26+
LL | String::from::utf16();
27+
| ^^^^^^^^^^^^
28+
|
29+
help: there is an associated function with a similar name: `from_utf16`
30+
|
31+
LL | String::from_utf16();
32+
| ~~~~~~~~~~
33+
34+
error[E0223]: ambiguous associated type
35+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:22:5
36+
|
37+
LL | String::from::method_that_doesnt_exist();
38+
| ^^^^^^^^^^^^
39+
|
40+
help: if there were a trait named `Example` with associated type `from` implemented for `String`, you could use the fully-qualified path
41+
|
42+
LL | <String as Example>::from::method_that_doesnt_exist();
43+
| ~~~~~~~~~~~~~~~~~~~~~~~~~
44+
45+
error[E0223]: ambiguous associated type
46+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:25:5
47+
|
48+
LL | str::into::string();
49+
| ^^^^^^^^^
50+
|
51+
help: there is an associated function with a similar name: `into_string`
52+
|
53+
LL | str::into_string();
54+
| ~~~~~~~~~~~
55+
56+
error[E0223]: ambiguous associated type
57+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:28:5
58+
|
59+
LL | str::char::indices();
60+
| ^^^^^^^^^
61+
|
62+
help: there is an associated function with a similar name: `char_indices`
63+
|
64+
LL | str::char_indices();
65+
| ~~~~~~~~~~~~
66+
67+
error[E0223]: ambiguous associated type
68+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:31:5
69+
|
70+
LL | Foo::bar::baz;
71+
| ^^^^^^^^
72+
|
73+
help: there is an associated function with a similar name: `bar_baz`
74+
|
75+
LL | Foo::bar_baz;
76+
| ~~~~~~~
77+
78+
error[E0223]: ambiguous associated type
79+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:34:5
80+
|
81+
LL | Foo::bar::quux;
82+
| ^^^^^^^^
83+
|
84+
help: there is an associated function with a similar name: `bar_quux`
85+
|
86+
LL | Foo::bar_quux;
87+
| ~~~~~~~~
88+
89+
error[E0223]: ambiguous associated type
90+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:37:5
91+
|
92+
LL | Foo::bar::fizz;
93+
| ^^^^^^^^
94+
|
95+
help: if there were a trait named `Example` with associated type `bar` implemented for `Foo`, you could use the fully-qualified path
96+
|
97+
LL | <Foo as Example>::bar::fizz;
98+
| ~~~~~~~~~~~~~~~~~~~~~
99+
100+
error[E0223]: ambiguous associated type
101+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:40:5
102+
|
103+
LL | i32::wrapping::add;
104+
| ^^^^^^^^^^^^^
105+
|
106+
help: there is an associated function with a similar name: `wrapping_add`
107+
|
108+
LL | i32::wrapping_add;
109+
| ~~~~~~~~~~~~
110+
111+
error[E0223]: ambiguous associated type
112+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:43:5
113+
|
114+
LL | i32::wrapping::method_that_doesnt_exist;
115+
| ^^^^^^^^^^^^^
116+
|
117+
help: if there were a trait named `Example` with associated type `wrapping` implemented for `i32`, you could use the fully-qualified path
118+
|
119+
LL | <i32 as Example>::wrapping::method_that_doesnt_exist;
120+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
121+
122+
error[E0223]: ambiguous associated type
123+
--> $DIR/ambiguous-assoc-type-path-suggest-similar-item.rs:48:5
124+
|
125+
LL | <dyn std::any::Any>::downcast::mut_unchecked;
126+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127+
|
128+
help: if there were a trait named `Example` with associated type `downcast` implemented for `(dyn Any + 'static)`, you could use the fully-qualified path
129+
|
130+
LL | <(dyn Any + 'static) as Example>::downcast::mut_unchecked;
131+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132+
133+
error: aborting due to 12 previous errors
134+
135+
For more information about this error, try `rustc --explain E0223`.

tests/ui/suggestions/issue-109195.rs

-20
This file was deleted.

tests/ui/suggestions/issue-109195.stderr

-69
This file was deleted.

0 commit comments

Comments
 (0)