In addition to disabling the warning, why does it happen?
use serde_json::from_str;
use serde_json::error::Result;
#[derive(Deserialize)]
pub struct Config {
#[serde(rename="cudaBlasDylibPath")]
pub cuda_blas_dylib_path: String,
}
impl Config {
pub fn new() -> Result<Config> {
from_str("{}")
}
}
src/config.rs:4:10: 4:21 warning: unused attribute, #[warn(unused_attributes)] on by default src/config.rs:4 #[derive(Deserialize)]
Adding #[allow(unused_attributes)]
doesn't help.
Here's the full output from the compiler:
src/main.rs:10:10: 10:21 warning: unused attribute, #[warn(unused_attributes)] on by default
src/main.rs:10 #[derive(Deserialize)]
^~~~~~~~~~~
src/main.rs:10:10: 10:21 note: in this expansion of #[derive_Deserialize] (defined in src/main.rs)
What this means is that the warning is within the code for the impl
generated by the #[derive]
attribute. However, it's hard to understand what's going on without seeing the code!
Fortunately, we can ask the compiler to show us the generated code. We need to pass additional parameters to rustc
, specifically -Z unstable-options --pretty=expanded
. If you're using Cargo, delete the compiled crate or run cargo clean
(Cargo does nothing if the target is up to date), then run this command:
$ cargo rustc -- -Z unstable-options --pretty=expanded > src/main-expanded.rs
We can then try to compile src/main-expanded.rs
with rustc
. If you're using Cargo, use the command Cargo prints when you run cargo build --verbose
(when the target is not up to date), but replace the name of the root source file with the new file we just generated – or you can just swap your main.rs
or lib.rs
with the expanded source. It might not always work, but when it does, it can provide some valuable insight.
We now get a clearer picture of the situation:
src/main-expanded.rs:17:5: 17:43 warning: unused attribute, #[warn(unused_attributes)] on by default
src/main-expanded.rs:17 #[serde(rename = "cudaBlasDylibPath")]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main-expanded.rs:20:1: 20:25 warning: unused attribute, #[warn(unused_attributes)] on by default
src/main-expanded.rs:20 #[automatically_derived]
^~~~~~~~~~~~~~~~~~~~~~~~
Here, the warning on the #[serde]
attribute is probably caused by the fact that the struct no longer has the #[derive(Deserialize)]
attribute, which is what processes the attribute. Also, it's not part of the expansion of the #[derive(Deserialize)]
attribute, so that's not the attribute the original warning complained about.
It looks like the #[automatically_derived]
attribute is the culprit here. This attribute appears to be used mainly by rustdoc (the documentation generation tool), but it has no meaning when compiling.
The implementation of #[derive]
for derivable traits known to rustc
emits the attribute like this:
let attr = cx.attribute(
self.span,
cx.meta_word(self.span,
InternedString::new("automatically_derived")));
// Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr);
My guess is that serde doesn't call the mark_used
function, which is what causes the warning. The only occurrences of "automatically_derived" in serde's source code are in invocations of the quote_item!
macro, which probably doesn't emit a call to mark_used
(and it should probably not do it either).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With