检查条件配置
rustc
接受 --check-cfg
选项,该选项指定是否检查条件以及如何检查。--check-cfg
选项接受一个值,称为 *检查 cfg 规范*。此规范具有一种形式
--check-cfg cfg(...)
将配置及其预期值标记为预期。
使用 --cfg
时不会添加隐式期望。用户应使用 *检查 cfg 规范* 传递所有预期名称和值。
cfg(...)
形式
cfg(...)
形式允许检查列表值条件中的值。它具有以下基本形式
rustc --check-cfg 'cfg(name, values("value1", "value2", ... "valueN"))'
其中 name
是一个裸标识符(没有引号),每个 "value"
项都是一个带引号的文字字符串。name
指定条件的名称,例如 feature
或 my_cfg
。
当指定 cfg(...)
选项时,rustc
将检查每个 #[cfg(name = "value")]
属性、#[cfg_attr(name = "value")]
属性、#[link(name = "a", cfg(name = "value"))]
属性和 cfg!(name = "value")
宏调用。它将检查指定的 "value"
是否存在于预期值的列表中。如果 "value"
不在其中,则 rustc
将报告 unexpected_cfgs
警告诊断。此警告的默认诊断级别为 Warn
。
命令行 --cfg
参数目前 *未* 检查,但将来可能会检查。
要检查 *none* 值(即 #[cfg(foo)]
),可以在 values()
中使用 none()
谓词:values(none())
。它可以位于任何数量的 "value"
之前或之后。
要启用值的检查,但要提供一个 *none* / 空的预期值集(即预期 #[cfg(name)]
),请使用以下形式
rustc --check-cfg 'cfg(name)'
rustc --check-cfg 'cfg(name, values(none()))'
要启用名称的检查但不启用值的检查,请使用以下形式之一
-
没有预期值(*将在每个值上发出警告*)
rustc --check-cfg 'cfg(name, values())'
-
未知预期值(*将永远不会发出警告*)
rustc --check-cfg 'cfg(name, values(any()))'
要避免重复相同的价值观,请使用以下形式
rustc --check-cfg 'cfg(name1, ..., nameN, values("value1", "value2", ... "valueN"))'
--check-cfg cfg(...)
选项可以重复,既可以针对相同的条件名称,也可以针对不同的名称。如果它针对相同的条件名称重复,则该条件的值集将合并在一起(优先级将赋予 values(any())
)。
众所周知的名称和值
rustc
具有一个内部列表,其中包含众所周知的名称及其对应值。这些众所周知的名称和值遵循与其引用的内容相同的稳定性。
只要存在至少一个 --check-cfg
参数,就会始终启用众所周知的名称和值检查。
截至 2024-04-06T
,已知名称列表如下
clippy
debug_assertions
doc
doctest
miri
overflow_checks
panic
proc_macro
relocation_model
sanitize
sanitizer_cfi_generalize_pointers
sanitizer_cfi_normalize_integers
target_abi
target_arch
target_endian
target_env
target_family
target_feature
target_has_atomic
target_has_atomic_equal_alignment
target_has_atomic_load_store
target_os
target_pointer_width
target_thread_local
target_vendor
test
ub_checks
unix
windows
与 values(any())
一样,可以通过将 cfg(any())
作为参数传递给 --check-cfg
来禁用众所周知的名称检查。
示例
等价表
此表描述了 --cfg
参数与 --check-cfg
参数的等价性。
--cfg | --check-cfg |
---|---|
无 | 无 或 --check-cfg=cfg() (启用检查) |
--cfg foo | --check-cfg=cfg(foo) 或 --check-cfg=cfg(foo, values(none())) |
--cfg foo="" | --check-cfg=cfg(foo, values("")) |
--cfg foo="bar" | --check-cfg=cfg(foo, values("bar")) |
--cfg foo="1" --cfg foo="2" | --check-cfg=cfg(foo, values("1", "2")) |
--cfg foo="1" --cfg bar="2" | --check-cfg=cfg(foo, values("1")) --check-cfg=cfg(bar, values("2")) |
--cfg foo --cfg foo="bar" | --check-cfg=cfg(foo, values(none(), "bar")) |
示例:类似 Cargo 的 feature
示例
考虑以下命令行
rustc --check-cfg 'cfg(feature, values("lion", "zebra"))' \
--cfg 'feature="lion"' -Z unstable-options example.rs
此命令行表明此板条箱具有两个功能:lion
和 zebra
。lion
功能已启用,而 zebra
功能已禁用。鉴于 --check-cfg
参数,已启用对名称和值的详尽检查。
example.rs
:
#[cfg(feature = "lion")] // This condition is expected, as "lion" is an expected value of `feature`
fn tame_lion(lion: Lion) {}
#[cfg(feature = "zebra")] // This condition is expected, as "zebra" is an expected value of `feature`
// but the condition will still evaluate to false
// since only --cfg feature="lion" was passed
fn ride_zebra(z: Zebra) {}
#[cfg(feature = "platypus")] // This condition is UNEXPECTED, as "platypus" is NOT an expected value of
// `feature` and will cause a compiler warning (by default).
fn poke_platypus() {}
#[cfg(feechure = "lion")] // This condition is UNEXPECTED, as 'feechure' is NOT a expected condition
// name, no `cfg(feechure, ...)` was passed in `--check-cfg`
fn tame_lion() {}
#[cfg(windows = "unix")] // This condition is UNEXPECTED, as while 'windows' is a well known
// condition name, it doesn't expect any values
fn tame_windows() {}
示例:多个名称和值
rustc --check-cfg 'cfg(is_embedded, has_feathers)' \
--check-cfg 'cfg(feature, values("zapping", "lasers"))' \
--cfg has_feathers --cfg 'feature="zapping"' -Z unstable-options
#[cfg(is_embedded)] // This condition is expected, as 'is_embedded' was provided in --check-cfg
fn do_embedded() {} // and doesn't take any value
#[cfg(has_feathers)] // This condition is expected, as 'has_feathers' was provided in --check-cfg
fn do_features() {} // and doesn't take any value
#[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as 'has_mumble_frotz' was NEVER provided
// in any --check-cfg arguments
fn do_mumble_frotz() {}
#[cfg(feature = "lasers")] // This condition is expected, as "lasers" is an expected value of `feature`
fn shoot_lasers() {}
#[cfg(feature = "monkeys")] // This condition is UNEXPECTED, as "monkeys" is NOT an expected value of
// `feature`
fn write_shakespeare() {}
示例:没有值的条件名称
rustc --check-cfg 'cfg(is_embedded, has_feathers, values(any()))' \
--cfg has_feathers -Z unstable-options
#[cfg(is_embedded)] // This condition is expected, as 'is_embedded' was provided in --check-cfg
// as condition name
fn do_embedded() {}
#[cfg(has_feathers)] // This condition is expected, as "has_feathers" was provided in --check-cfg
// as condition name
fn do_features() {}
#[cfg(has_feathers = "zapping")] // This condition is expected, as "has_feathers" was provided in
// and because *any* values is expected for 'has_feathers' no
// warning is emitted for the value "zapping"
fn do_zapping() {}
#[cfg(has_mumble_frotz)] // This condition is UNEXPECTED, as 'has_mumble_frotz' was not provided
// in any --check-cfg arguments
fn do_mumble_frotz() {}