使用 Serde 库时如何禁用 "unused attribute" 警告?
How can I disable the "unused attribute" warning when using Serde library?
除了禁用警告,为什么会发生?
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)]
添加 #[allow(unused_attributes)]
没有帮助。
编译器的完整输出如下:
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,请删除已编译的箱子或 运行 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.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)]
属性是处理该属性的。此外,它不是 #[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 源代码中 "automatically_derived" 的 only occurrences 是在 quote_item!
宏的调用中,它可能不会发出对 mark_used
的调用(它可能不应该这样做)要么)。
除了禁用警告,为什么会发生?
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)]
添加 #[allow(unused_attributes)]
没有帮助。
编译器的完整输出如下:
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,请删除已编译的箱子或 运行 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.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)]
属性是处理该属性的。此外,它不是 #[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 源代码中 "automatically_derived" 的 only occurrences 是在 quote_item!
宏的调用中,它可能不会发出对 mark_used
的调用(它可能不应该这样做)要么)。