Skip to content

Commit

Permalink
Unrolled build for rust-lang#135865
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rust-timer authored Jan 24, 2025
2 parents 48ef38d + 2c58212 commit b0418f2
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 96 deletions.
20 changes: 14 additions & 6 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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")
Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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`
}
Original file line number Diff line number Diff line change
@@ -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`.
20 changes: 0 additions & 20 deletions tests/ui/suggestions/issue-109195.rs

This file was deleted.

69 changes: 0 additions & 69 deletions tests/ui/suggestions/issue-109195.stderr

This file was deleted.

0 comments on commit b0418f2

Please sign in to comment.