Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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.
estebank added a commit to estebank/rust that referenced this issue Dec 28, 2024
```
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 Dec 28, 2024
```
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 Jan 24, 2025
```
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 Mar 9, 2025
```
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.
# for free to join this conversation on GitHub. Already have an account? # 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