Repository: rust
Issue: rustc should magically detect repeating refactoring errors and compress them
Labels: A-diagnostics,A-macros,T-compiler

This error report is now live as a repo:

https://github.com/workingjubilee/uwu-er-i-mean-owo

### Code


If you have code that looks like this:
```rust
#[macro_use]
macro_rules! uwuify {
    ($($this:ident),*) => {
        $(
        impl WhatsThis for $this {
            fn uwu() -> Self {
                <$this as Default>::default()
            }
        }
        )*
    }
}
mod ty0;
mod ty1;
mod ty2;
mod ty3;
mod ty4;
mod ty5;
mod ty6;
mod ty7;
mod ty8;
mod ty9;

trait WhatsThis {
    fn uwu() -> Self;
}

impl WhatsThis for SomeType {
    fn uwu() -> Self {
        SomeType::less_trivial_constructor(SOME_CONSTANT)
    }
}
```

Where each `mod` has some contents like this:
```rust
#[derive(Default)]
pub struct Ty0 {}

uwuify!(Ty0);
```

Then change the code this way:

```diff
 trait WhatsThis {
-    fn uwu() -> Self;
+    fn owo() -> Self;
 }
 
 impl WhatsThis for SomeType {
-    fn uwu() -> Self {
+    fn owo() -> Self {
         SomeType::less_trivial_constructor(SOME_CONSTANT)
     }
 }
```

The problem here is that I forgot to rename the items in the macro appropriately, and this is frequently missed by the way rust-analyzer's bulk-refactoring is integrated in at least some editors. We now get this error:


### Current output

```console
$ cargo check
    Checking whats-this v0.1.0 (/home/jubilee/rust/whats-this)
error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty0.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty0);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty1.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty1);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty2.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty2);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty3.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty3);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty4.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty4);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty5.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty5);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty6.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty6);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty7.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty7);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty8.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty8);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty9.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty9);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: `#[macro_use]` only has an effect on `extern crate` and modules
 --> src/main.rs:9:1
  |
9 | #[macro_use]
  | ^^^^^^^^^^^^
  |
  = note: `#[warn(unused_attributes)]` on by default

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty0.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty0);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty1.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty1);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty2.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty2);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty3.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty3);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty4.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty4);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty5.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty5);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty6.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty6);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty7.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty7);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty8.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty8);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty9.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty9);
   | |_____- in this macro invocation
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0046, E0407.
For more information about an error, try `rustc --explain E0046`.
warning: `whats-this` (bin "whats-this") generated 1 warning
error: could not compile `whats-this` (bin "whats-this") due to 20 previous errors; 1 warning emitted
```


### Desired output

```console
error[E0407]: method `uwu` is not a member of trait `WhatsThis`
  --> src/main.rs:14:13
   |
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`
   |
  ::: src/ty9.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty9);
   | |_____- in this macro invocation and 9 others
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0046]: not all trait items implemented, missing: `owo`
  --> src/main.rs:13:9
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
   |
  ::: src/ty9.rs:4:1
   |
4  | / uwuify
5  | | !
6  | | (Ty9);
   | |_____- in this macro invocation and 9 others
   |
   = note: this error originates in the macro `uwuify` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0046, E0407.
For more information about an error, try `rustc --explain E0046`.
warning: `whats-this` (bin "whats-this") generated 1 warning
error: could not compile `whats-this` (bin "whats-this") due to 20 previous errors; 1 warning emitted
```


### Rationale and extra context

The preferred output is to swallow these into a single error, since the rest is just terminal spam, basically. Even pointing at different *files* where this error occurs is not very helpful, as the actual issue is I need to rename something in the macro.

It seems rustc is *just* smart enough to swallow this if this is a repeating macro error in the same file (possibly the same macro invocation, haven't experimented beyond this), but that's not always the case, and "how (not) well-factored my code is" would ideally matter less to diagnostics.

As a bonus round: rustc could notice these two errors, recognize they're similar signatures except for names, and just ask me directly if I forgot to rename something, like:
```
error[E0407]: expanded `impl WhatsThis for $this` is missing a trait item: `owo`
  --> src/main.rs:14:13
   |
13 |           impl WhatsThis for $this {
   |           ^^^^^^^^^^^^^^^^^^^^^^^^ missing `owo` in implementation
...
33 |       fn owo() -> Self;
   |       ----------------- `owo` from trait
= note: `impl WhatsThis for $this` also has an item that is not a member of `trait WhatsThis`
14 | /             fn uwu() -> Self {
15 | |                 <$this as Default>::default()
16 | |             }
   | |_____________^ not a member of trait `WhatsThis`

= help: perhaps you meant to rename the item from `fn uwu` to `fn owo`?
```

### Other cases

_No response_

### Rust Version

```Shell
rustc 1.80.0-nightly (ab14f944a 2024-05-13)
binary: rustc
commit-hash: ab14f944afe4234db378ced3801e637eae6c0f30
commit-date: 2024-05-13
host: x86_64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.4
```


### Anything else?

@rustbot label: +A-macros