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

Misleading diagnostics with missing bounds when deriving a trait #84003

Closed
a1phyr opened this issue Apr 8, 2021 · 1 comment · Fixed by #90519
Closed

Misleading diagnostics with missing bounds when deriving a trait #84003

a1phyr opened this issue Apr 8, 2021 · 1 comment · Fixed by #90519
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-proc-macros Area: Procedural macros D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@a1phyr
Copy link
Contributor

a1phyr commented Apr 8, 2021

Given the following code: https://play.rust-lang.org/?edition=2018&gist=5f8c9b8b72174c48746e236c827ab881

use std::fmt;

trait Trait {}

struct X<T>(T);

impl<T: fmt::Debug + Trait> fmt::Debug for X<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("X").field(&self.0).finish()
    }
}

#[derive(Debug)]
struct Y<T>(X<T>);

The current output is:

error[E0277]: the trait bound `T: Trait` is not satisfied
  --> src/lib.rs:14:13
   |
14 | struct Y<T>(X<T>);
   |             ^^^^ the trait `Trait` is not implemented for `T`
   |
   = note: required because of the requirements on the impl of `Debug` for `X<T>`
   = note: 1 redundant requirements hidden
   = note: required because of the requirements on the impl of `Debug` for `&X<T>`
   = note: required for the cast to the object type `dyn Debug`
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
   |
13 | #[derive(Debug + Trait)]
   |                ^^^^^^^

The proposed solution is obviously wrong, the compiler should suggest a manual impl instead.

@a1phyr a1phyr added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 8, 2021
@estebank estebank added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-proc-macros Area: Procedural macros D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels Apr 9, 2021
@lo48576
Copy link
Contributor

lo48576 commented Nov 1, 2021

I found another variation, where adding where clause is suggested inside derive.

Source (https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=20c02bc28c88fbc15614319fa7509fbd):

use std::fmt;

trait DebugExt: fmt::Debug {}

pub struct Inner<T>(T);

impl fmt::Debug for Inner<()> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        todo!()
    }
}

#[derive(Debug)]
pub struct Outer<T>(Inner<T>);

Compiler output:

error[E0277]: `Inner<T>` doesn't implement `Debug`
  --> src/lib.rs:14:21
   |
13 | #[derive(Debug)]
   |          ----- in this derive macro expansion
14 | pub struct Outer<T>(Inner<T>);
   |                     ^^^^^^^^ `Inner<T>` cannot be formatted using `{:?}`
   |
   = help: the trait `Debug` is not implemented for `Inner<T>`
   = note: add `#[derive(Debug)]` to `Inner<T>` or manually `impl Debug for Inner<T>`
   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
   |
13 | #[derive(Debug where Inner<T>: Debug)]
   |                +++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 4, 2021
Keep spans for generics in `#[derive(_)]` desugaring

Keep the spans for generics coming from a `derive`d Item, so that errors
and suggestions have better detail.

Fix rust-lang#84003.
@bors bors closed this as completed in e70105f Dec 4, 2021
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 A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-proc-macros Area: Procedural macros D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants