Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I disable the "unused attribute" warning when using Serde library?

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.

like image 661
ababo Avatar asked Nov 25 '15 19:11

ababo


1 Answers

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).

like image 111
Francis Gagné Avatar answered Nov 15 '22 04:11

Francis Gagné