这是编译器的完整输出:
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)
这意味着警告在属性impl
生成的代码中。#[derive]
但是,如果不看代码,很难理解发生了什么!
幸运的是,我们可以要求编译器向我们展示生成的代码。我们需要将额外的参数传递给rustc
,特别是-Z unstable-options --pretty=expanded
. 如果您正在使用 Cargo,请删除已编译的 crate 或运行cargo clean
(如果目标是最新的,则 Cargo 不会执行任何操作),然后运行以下命令:
$ cargo rustc -- -Z unstable-options --pretty=expanded > src/main-expanded.rs
然后我们可以尝试src/main-expanded.rs
用rustc
. 如果您使用 Cargo,请在运行时使用 Cargo 打印命令cargo build --verbose
(当目标不是最新的时),但将根源文件的名称替换为我们刚刚生成的新文件 - 或者您可以交换您的main.rs
或lib.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(文档生成工具)使用,但在编译时没有任何意义。
#[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);
我的猜测是 serde 没有调用该mark_used
函数,这就是导致警告的原因。在 serde的源代码中唯一 出现的“自动派生”是在quote_item!
宏的调用中,它可能不会发出对的调用mark_used
(而且它可能也不应该这样做)。