Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Friendlier compiler message for incorrect trait method signatures #28011

Closed
andersforsgren opened this issue Aug 26, 2015 · 4 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@andersforsgren
Copy link

When implementing a trait, it would be useful to see the expected method signature in compiler error messages. Example

impl std::fmt::Display for MyType {
   // Not sure what to put here so I stub it and hope to get help from error
   fn fmt() -> () { } 
}   

The current error message for E0186 only lets me partially resolve the issue:

error: method `fmt` has a `&self` declaration in the trait, but not in the impl [E0186]

It would be more friendly to the user if the message showed both the actual and expected method signatures.

Incorrect method signature for trait `Display` method `fmt`
Actual signature    fn fmt() -> ()
Expected signature  fn fmt(&self, &mut Formatter) -> Result<(), Error>
@jdm jdm added the A-diagnostics Area: Messages for errors, warnings, and lints label Aug 26, 2015
@nagisa
Copy link
Member

nagisa commented Aug 26, 2015

I wanted similar behaviour occasionally as well. Looking signatures up in the docs is painful.

@birkenfeld
Copy link
Contributor

related: #24626, which requests the same for missing methods in impls.

estebank added a commit to estebank/rust that referenced this issue Sep 10, 2016
Given file `foo.rs`:

```rust
struct A {}

impl std::fmt::Display for A {
    fn fmt() -> () {}
}
```

provide the expected method signature:

```bash
error: main function not found

error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in the impl
 --> foo.rs:4:5
  |
4 |     fn fmt() -> () {}
  |     ^^^^^^^^^^^^^^^^^ expected `&self` in impl
  |
  = note: Expected signature: fn fmt(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>;
  = note:    Found signature: fn fmt();

error: aborting due to previous error
```

Fixes rust-lang#28011
estebank added a commit to estebank/rust that referenced this issue Oct 1, 2016
For a given file `foo.rs`:

```rust
use std::str::FromStr;

struct A {}

trait X<T> {
    type Foo;
    const BAR: u32 = 128;

    fn foo() -> T;
    fn bar();
    fn    bay<
        'lifetime,    TypeParameterA
            >(  a   : usize,
                b: u8  );
}

impl std::fmt::Display for A {
}
impl FromStr for A{}

impl X<usize> for A {
}
```

Provide the following output:

```bash
error: main function not found

error[E0046]: not all trait items implemented, missing: `fmt`
  --> foo.rs:18:1
   |
18 | impl std::fmt::Display for A {
   | ^ missing `fmt` in implementation
   |
   = note: fn fmt(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>;

error[E0046]: not all trait items implemented, missing: `Err`, `from_str`
  --> foo.rs:20:1
   |
20 | impl FromStr for A{}
   | ^^^^^^^^^^^^^^^^^^^^ missing `Err`, `from_str` in implementation
   |
   = note: type Err;
   = note: fn from_str(&str) -> std::result::Result<Self, <Self as std::str::FromStr>::Err>;

error[E0046]: not all trait items implemented, missing: `Foo`, `foo`, `bar`, `bay`
  --> foo.rs:22:1
   |
22 | impl X<usize> for A {
   | ^ missing `Foo`, `foo`, `bar`, `bay` in implementation
   |
   = note: type Foo;
   = note: fn foo() -> T;
   = note: fn bar();
   = note: fn bay<'lifetime, TypeParameterA>(a: usize, b: u8);

error: aborting due to 3 previous errors
```

Fixes rust-lang#24626

For a given file `foo.rs`:

```rust
struct A {}

impl std::fmt::Display for A {
    fn fmt() -> () {}
}
```

provide the expected method signature:

```bash
error: main function not found

error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in the impl
 --> foo.rs:4:5
  |
4 |     fn fmt() -> () {}
  |     ^^^^^^^^^^^^^^^^^ expected `&self` in impl
  |
  = note: Expected signature: fn fmt(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>;
  = note:    Found signature: fn fmt();

error: aborting due to previous error
```

Fixes rust-lang#28011
@estebank
Copy link
Contributor

Related: #37370.

@steveklabnik steveklabnik removed the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@Mark-Simulacrum
Copy link
Member

Worth pointing out that the signature is relatively easy to get today if the method is removed. Still a problem though.

bors added a commit that referenced this issue Jun 4, 2017
Show trait method signature when impl differs

When the trait's span is available, it is already being used, add a
`note` for the cases where the span isn't available:

<pre>
error[E0053]: <b>method `fmt` has an incompatible type for trait</b>
  --> $DIR/trait_type.rs:17:4
   |
17 |    fn fmt(&self, x: &str) -> () { }
   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
   |
   = note: expected type `<b>fn(&MyType, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error></b>`
              found type `<b>fn(&MyType, &str)</b>`

error[E0050]: <b>method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2</b>
  --> $DIR/trait_type.rs:21:11
   |
21 |    fn fmt(&self) -> () { }
   |           ^^^^^ expected 2 parameters, found 1
   |
   = note: `fmt` from trait: `<b>fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error></b>`

error[E0186]: <b>method `fmt` has a `&self` declaration in the trait, but not in the impl</b>
  --> $DIR/trait_type.rs:25:4
   |
25 |    fn fmt() -> () { }
   |    ^^^^^^^^^^^^^^^^^^ expected `&self` in impl
   |
   = note: `fmt` from trait: `<b>fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error></b>`

error[E0046]: <b>not all trait items implemented, missing: `fmt`</b>
  --> $DIR/trait_type.rs:28:1
   |
28 | impl std::fmt::Display for MyType4 {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
   |
   = note: `fmt` from trait: `<b>fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error></b>`
</code></pre>

Fix #28011.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints
Projects
None yet
Development

No branches or pull requests

7 participants