Poor error message when user forgets derive that has attributes
#[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.
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?
David Tolnay at 2018-01-20 05:57:24
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
keeperofdakeys at 2018-01-20 21:40:57
What should the diagnostic text be for the following cases?:
#[macro_use] extern crate serde_derive;(the presented case in the description): user forgot to use#[derive]extern crate serde_derive;: user forgot to add#[macro_use]- user forgot to add the
serdecrate to the project in the code - user forgot to add the
serdecrate to thetomlconfig 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 :-/
Esteban Kuber at 2018-07-19 17:51:03
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 insertingDeserializeinto the list of derives if there is already a derive attribute.David Tolnay at 2018-07-19 18:05:36
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 enableNemo157 at 2018-10-05 09:28:40
Yeah, this bit me hard yesterday.
Steve Klabnik at 2018-10-05 14:36:52
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 featureserde_deriveis not specified forserdeand 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.Alexander Irbis at 2019-01-29 10:16:21
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, https://github.com/rust-lang/rust/pull/56999 probably.
Vadim Petrochenkov at 2019-01-29 10:23:13
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); | ^^^^^Paul-Sebastian Manole at 2020-02-09 23:11:41
I'm working on a PR for this <img width="1026" alt="Screenshot 2023-03-17 at 11 25 35 AM" src="https://user-images.githubusercontent.com/1606434/225988757-9ef8077e-b3b9-45f6-8ebf-0a0ea104e9da.png">
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.Esteban Kuber at 2023-03-17 18:31:20