【问题标题】:How can I disable the "unused attribute" warning when using Serde library?使用 Serde 库时如何禁用“未使用属性”警告?
【发布时间】:2015-11-25 19:58:08
【问题描述】:

除了禁用警告之外,为什么会这样?

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 警告:未使用的属性,#[warn(unused_attributes)] 默认开启 src/config.rs:4 #[derive(Deserialize)]

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

【问题讨论】:

    标签: json rust deserialization serde


    【解决方案1】:

    这是编译器的完整输出:

    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)
    

    这意味着警告在#[derive] 属性生成的impl 的代码中。但是,不看代码很难理解是怎么回事!

    幸运的是,我们可以要求编译器向我们展示生成的代码。我们需要将额外的参数传递给rustc,特别是-Z unstable-options --pretty=expanded。如果您使用 Cargo,请删除已编译的 crate 或运行 cargo clean(如果目标是最新的,则 Cargo 不会执行任何操作),然后运行以下命令:

    $ cargo rustc -- -Z unstable-options --pretty=expanded > src/main-expanded.rs
    

    然后我们可以尝试用rustc 编译src/main-expanded.rs。如果您使用 Cargo,请在运行 cargo build --verbose 时使用 Cargo 打印命令(当目标不是最新的时),但将根源文件的名称替换为我们刚刚生成的新文件 - 或者您可以将您的 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]
                            ^~~~~~~~~~~~~~~~~~~~~~~~
    

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

    看起来#[automatically_derived] 属性是这里的罪魁祸首。这个属性貌似主要被rustdoc(文档生成工具)使用,但是编译的时候没有任何意义。

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

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

    我的猜测是 serde 没有调用 mark_used 函数,这就是导致警告的原因。 serde 源代码中“automatically_derived”的onlyoccurrences 是在调用quote_item! 宏时,它可能不会发出对mark_used 的调用(它可能也不应该这样做)。

    【讨论】:

    • 我认为你可以运行cargo rustc -Z unstable-options --pretty=expanded。无需从详细输出中提取rustc 命令。
    • 感谢您如此完整而认真的解释。唯一缺少的答案是关于如何解决这个问题。
    • @VladimirMatveev:感谢您提供的信息。实际上,您需要在传递给rustc 的参数前加上--,然后,如果目标是最新的,Cargo 将不会运行rustc
    • @ababo,我认为这可能是 serde 本身的问题。将此问题报告给其问题跟踪器可能是有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    相关资源
    最近更新 更多