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

Poor error message when user forgets derive that has attributes #47608

Open
dtolnay opened this issue Jan 20, 2018 · 10 comments
Open

Poor error message when user forgets derive that has attributes #47608

dtolnay opened this issue Jan 20, 2018 · 10 comments
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 C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@dtolnay
Copy link
Member

dtolnay commented Jan 20, 2018

#[macro_use]
extern crate serde_derive;

#[serde(untagged)]
enum CellIndex {
    Auto,
    Index(u32),
}
error[E0658]: The attribute `serde` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
 --> src/main.rs:4:1
  |
4 | #[serde(untagged)]
  | ^^^^^^^^^^^^^^^^^^
  |
  = help: add #![feature(custom_attribute)] to the crate attributes to enable

The error and suggestion are super misleading and I have seen this a few times in #serde. It should be possible for the compiler to observe that there are derive macros in scope with serde declared as an attribute, and suggest using those.

// These are in scope
#[proc_macro_derive(Serialize, attributes(serde))]
#[proc_macro_derive(Deserialize, attributes(serde))]

A better message would not have the part about the compiler adding meaning to #[serde] in the future and would recommend using #[derive(Serialize)] or #[derive(Deserialize)] on the struct containing the attribute.

@dtolnay
Copy link
Member Author

dtolnay commented Jan 20, 2018

Mentioning @keeperofdakeys who implemented attribute support for derives in #37614.
Mentioning @topecongiro who worked on derive macro improvements recently in #47013.

Would either of you be interested in following up with an improved error message for this case?

@keeperofdakeys
Copy link
Contributor

keeperofdakeys commented Jan 20, 2018

This error message could be a bit misleading. What if they really wanted a proc macro and forgot to import it? What if derives from multiple crates use the same attribute? What if the derive macro hasn't been imported?

It is a nice solution though, and I'd be interested in more views about it.

Edit: And I'm happy to implement this if required.

Irrespective of this, the generic error message should have something like "did you forget to import a proc macro, or define a #[derive] for this item?" added to it.

ping @jseyfried @nrc

@TimNN TimNN added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-diagnostics Area: Messages for errors, warnings, and lints labels Jan 23, 2018
@estebank
Copy link
Contributor

What should the diagnostic text be for the following cases?:

  1. #[macro_use] extern crate serde_derive; (the presented case in the description): user forgot to use #[derive]
  2. extern crate serde_derive;: user forgot to add #[macro_use]
  3. user forgot to add the serde crate to the project in the code
  4. user forgot to add the serde crate to the toml config file

I can see how we can provide good diagnostics for cases 1 and 2, maybe for case 3, but I'm intrigued by what the appropriate text for case 4 might be for newcomers, short of a whitelist of attributes from popular crates :-/

@dtolnay
Copy link
Member Author

dtolnay commented Jul 19, 2018

Your case 1 is the only one I have seen over and over again in IRC. I wouldn't bother with the other cases. For case 1 I would like a diagnostic like this:

error[E...]: The attribute `serde` is provided by derive(Serialize) or derive(Deserialize); one of these must be derived on `CellIndex` for this attribute to be available
 --> src/main.rs:4:1
  |
4 | #[serde(untagged)]
  | ^^^^^^^^^^^^^^^^^^

along with a suggested fix that shows adding the (I guess alphanumerically the first, if there is more than one in scope) derive as a new #[derive(Deserialize)] attribute above the type if there are not already any derives on that type, or inserting Deserialize into the list of derives if there is already a derive attribute.

@Nemo157
Copy link
Member

Nemo157 commented Oct 5, 2018

There's a much more likely reproducer of case 2 on edition 2018, if you simply forget to use serde_derive::Serialize;

#[derive(Serialize)]
#[serde(untagged)]
enum CellIndex {
    Auto,
    Index(u32),
}

gives the same error and doesn't mention the missing derive at all

error[E0658]: The attribute `serde` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
 --> src/main.rs:2:3
  |
2 | #[serde(untagged)]
  |   ^^^^^
  |
  = help: add #![feature(custom_attribute)] to the crate attributes to enable

@steveklabnik
Copy link
Member

Yeah, this bit me hard yesterday.

@estebank estebank added the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label Jan 22, 2019
@alexander-irbis
Copy link

alexander-irbis commented Jan 29, 2019

It is especially difficult to figure out what happens when #[derive(De/Serialize) is in place, but something went wrong with the import. For example, the feature serde_derive is not specified for serde and there is some other issues in code, the error message is just about #[serde(...)]. Only after every possible simplification of the code and the correction of potential errors, a message appears that the derived trait is not a macro.

@petrochenkov
Copy link
Contributor

The error message now says that the derive macro is unresolved when #[derive(De/Serialize) is in place:

error[E0658]: The attribute `serde` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
 --> src/main.rs:2:3
  |
2 | #[serde(untagged)]
  |   ^^^^^
  |
  = help: add #![feature(custom_attribute)] to the crate attributes to enable

error: cannot find derive macro `Serialize` in this scope
 --> src/main.rs:1:10
  |
1 | #[derive(Serialize)]
  |          ^^^^^^^^^

This was fixed somewhere between stable and beta in one of PRs improving error recovery, #56999 probably.

@brokenthorn
Copy link

Had similar issue with Rust 2018 and this code:

#[derive(Serialize)] // where I forgot this line
#[serde(remote = "StatusCode")]
struct StatusCodeDef(#[serde(getter = "StatusCode::as_u16")] u16);

impl From<StatusCodeDef> for StatusCode {
    fn from(def: StatusCodeDef) -> Self {
        StatusCode::from_u16(def.0).unwrap()
    }
}

and the error was:

error: cannot find attribute `serde` in this scope
  --> src/error.rs:11:3
   |
11 | #[serde(remote = "StatusCode")]
   |   ^^^^^

error: cannot find attribute `serde` in this scope
  --> src/error.rs:12:24
   |
12 | struct StatusCodeDef(#[serde(getter = "StatusCode::as_u16")] u16);
   |                        ^^^^^

@estebank estebank added D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 11, 2020
@Aaron1011 Aaron1011 added the A-proc-macros Area: Procedural macros label May 21, 2020
@estebank
Copy link
Contributor

estebank commented Mar 17, 2023

I'm working on a PR for this
Screenshot 2023-03-17 at 11 25 35 AM

error: cannot find attribute `sede` in this scope
  --> src/main.rs:18:7
   |
18 |     #[sede(untagged)]
   |       ^^^^
   |
help: the derive macros `Serialize` and `Deserialize` accept the similarly named `serde` attribute
   |
18 |     #[serde(untagged)]
   |       ~~~~~

error: cannot find attribute `serde` in this scope
  --> src/main.rs:12:7
   |
12 |     #[serde(untagged)]
   |       ^^^^^
   |
   = note: `serde` is in scope, but it is a crate, not an attribute
help: `serde` is an attribute that can be used by the derive macros `Serialize` and `Deserialize`, you might be missing a `derive` attribute
   |
10 | #[derive(Serialize, Deserialize)]
   |

For now it only works if use serde::Serialize; is present.

Edit:

The suggestion will now happen as long as at least use serde; is involved somewhere in the crate. I feel like that might be enough for unblocking most people.

estebank added a commit to estebank/rust that referenced this issue Mar 30, 2023
```
error: cannot find attribute `sede` in this scope
  --> src/main.rs:18:7
   |
18 |     #[sede(untagged)]
   |       ^^^^
   |
help: the derive macros `Serialize` and `Deserialize` accept the similarly named `serde` attribute
   |
18 |     #[serde(untagged)]
   |       ~~~~~

error: cannot find attribute `serde` in this scope
  --> src/main.rs:12:7
   |
12 |     #[serde(untagged)]
   |       ^^^^^
   |
   = note: `serde` is in scope, but it is a crate, not an attribute
help: `serde` is an attribute that can be used by the derive macros `Serialize` and `Deserialize`, you might be missing a `derive` attribute
   |
10 | #[derive(Serialize, Deserialize)]
   |
```

Mitigate rust-lang#47608.
estebank added a commit to estebank/rust that referenced this issue Apr 14, 2023
```
error: cannot find attribute `sede` in this scope
  --> src/main.rs:18:7
   |
18 |     #[sede(untagged)]
   |       ^^^^
   |
help: the derive macros `Serialize` and `Deserialize` accept the similarly named `serde` attribute
   |
18 |     #[serde(untagged)]
   |       ~~~~~

error: cannot find attribute `serde` in this scope
  --> src/main.rs:12:7
   |
12 |     #[serde(untagged)]
   |       ^^^^^
   |
   = note: `serde` is in scope, but it is a crate, not an attribute
help: `serde` is an attribute that can be used by the derive macros `Serialize` and `Deserialize`, you might be missing a `derive` attribute
   |
10 + #[derive(Serialize, Deserialize)]
11 | struct Foo {
   |
```

Mitigate rust-lang#47608.
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 C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. 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.

10 participants