Repository: rust
Issue: [ER] Possible improvements for impl block and self object errrors diagnostic
Labels: A-diagnostics,T-compiler

This is a diagnostic enhancement request. It's meant to improve a bit the life of new Rust programmers coming from other languages such as Java.

```rust
struct Foo {
    x: u32,

    fn inc(&mut self) {
        self.x += 1;
    }
}
fn main() {}
```
rustc (1.53.0-nightly 5a4ab2645 2021-04-18) gives:

```rust
error: expected identifier, found keyword `fn`
 --> ...\test.rs:4:5
  |
4 |     fn inc(&mut self) {
  |     ^^ expected identifier, found keyword

error: aborting due to previous error
```

Expected: a suggestion to move the method inc into an impl block.

- - - - - - - - - - - - - - - - - - - - - - - - - -

```rust
struct Foo {
    x: u32,
}
impl Foo {
    fn inc1() {
        this.x += 1;
    }
    fn inc2(&this) {
        this.x += 1;
    }
    fn inc3(&mut this) {
        this.x += 1;
    }
    fn inc4() {
        self.x += 1;
    }
}
fn main() {}
```

rustc gives:

```rust
error: expected one of `:`, `@`, or `|`, found `)`
 --> ...\test.rs:8:18
  |
8 |     fn inc2(&this) {
  |                  ^ expected one of `:`, `@`, or `|`
  |
  = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
help: if this is a `self` type, give it a parameter name
  |
8 |     fn inc2(self: &this) {
  |             ^^^^^^^^^^^
help: if this is a parameter name, give it a type
  |
8 |     fn inc2(this: &TypeName) {
  |             ^^^^^^^^^^^^^^^
help: if this is a type, explicitly ignore the parameter name
  |
8 |     fn inc2(_: &this) {
  |             ^^^^^^^^

error: expected one of `:`, `@`, or `|`, found `)`
  --> ...\test.rs:11:22
   |
11 |     fn inc3(&mut this) {
   |                      ^ expected one of `:`, `@`, or `|`
   |
   = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
help: if this is a `self` type, give it a parameter name
   |
11 |     fn inc3(self: &mut this) {
   |             ^^^^^^^^^^^^^^^
help: if this is a parameter name, give it a type
   |
11 |     fn inc3(this: &mut TypeName) {
   |             ^^^^^^^^^^^^^^^^^^^
help: if this is a type, explicitly ignore the parameter name
   |
11 |     fn inc3(_: &mut this) {
   |             ^^^^^^^^^^^^

error[E0425]: cannot find value `this` in this scope
 --> ...\test.rs:6:9
  |
6 |         this.x += 1;
  |         ^^^^ not found in this scope
  |
help: you might have meant to use `self` here instead
  |
6 |         self.x += 1;
  |         ^^^^
help: if you meant to use `self`, you are also missing a `self` receiver argument
  |
5 |     fn inc1(&self) {
  |             ^^^^^

error[E0424]: expected value, found module `self`
  --> ...\test.rs:15:9
   |
14 |     fn inc4() {
   |        ---- this function doesn't have a `self` parameter
15 |         self.x += 1;
   |         ^^^^ `self` value is a keyword only available in methods with a `self` parameter
   |
help: add a `self` receiver parameter to make the associated `fn` a method
   |
14 |     fn inc4(&self) {
   |             ^^^^^

error: aborting due to 4 previous errors
```

Expected:
- Error messages to be sorted on the number line. So I think they should be ordered in the 6 8 11 14 sequence.
- Perhaps the "anonymous parameters are removed in the 2018 edition (see RFC 1685)" is obsolete and could be removed or reduced.
- Where it suggests to add (&self) it should better suggest (&mut self).