如何在使用Serde库时禁用"unused attribute"警告?

aba*_*abo 5 json rust deserialization serde

除了禁用警告,为什么会发生?

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("{}")
    }
}
Run Code Online (Sandbox Code Playgroud)

src/config.rs:4:10:4:21警告:未使用的属性,#[warn(unused_attributes)]默认为src/config.rs:4#[derive(Deserialize)]

添加#[allow(unused_attributes)]没有帮助.

Fra*_*gné 5

这是编译器的完整输出:

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)
Run Code Online (Sandbox Code Playgroud)

这意味着警告impl#[derive]属性生成的代码中.但是,如果没有看到代码,很难理解发生了什么!

幸运的是,我们可以要求编译器向我们展示生成的代码.我们需要通过额外的参数rustc,具体-Z unstable-options --pretty=expanded.如果您正在使用Cargo,请删除已编译的包或运行cargo clean(如果目标是最新的,则Cargo不执行任何操作),然后运行以下命令:

$ cargo rustc -- -Z unstable-options --pretty=expanded > src/main-expanded.rs
Run Code Online (Sandbox Code Playgroud)

然后,我们可以尝试编译src/main-expanded.rs使用rustc.如果您正在使用Cargo,请在运行cargo build --verbose时使用命令Cargo prints (当目标不是最新时),但使用我们刚生成的新文件替换根源文件的名称 - 或者您可以只是交换您的main.rslib.rs扩展的来源.它可能并不总是有效,但是当它确实有效时,它可以提供一些有价值的见解.

我们现在可以更清楚地了解情况:

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]
                        ^~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

这里,对#[serde]属性的警告可能是由于struct不再具有#[derive(Deserialize)]属性的事实引起的,该属性处理属性.此外,它不是#[derive(Deserialize)]属性扩展的一部分,因此不是原始警告所抱怨的属性.

看起来#[automatically_derived]属性是罪魁祸首.该属性似乎主要由rustdoc(文档生成工具)使用,但在编译时没有任何意义.

#[derive]已知可派生特征的实现rustc会发出如下属性:

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);
Run Code Online (Sandbox Code Playgroud)

我的猜测是,serde不会调用mark_used函数,这就是导致警告的原因.该 出现在SERDE的源代码"automatically_derived"都在的调用quote_item!宏,它可能不会发出一个呼叫mark_used(它可能不应该这样做,要么).