【问题标题】:Is there a way to enforce correct spelling of features?有没有办法强制正确拼写特征?
【发布时间】:2021-11-30 19:45:27
【问题描述】:

假设我在Cargo.toml 中定义了以下功能:

[features]
my_feature = []

以下代码位于src/lib.rs

#[cfg(feature = "my_feature")]
fn f() { /* ... */ }

#[cfg(not(feature = "my_faeture"))] // <-- Mind the typo!
fn f() { /* ... */ }

我如何强制特征字符串与Cargo.toml 中显式定义和隐式可用特征的列表相匹配,从而避免例如拼写错误?

【问题讨论】:

  • Clippy 应该有 lint 的东西,但显然没有。
  • 我坚信这应该是rustc 的责任。例如,您可以传递一组您希望编译器强制执行的功能,而不是将这个责任进一步推给 linter,这是非常可选的。
  • rustc 对Cargo.toml 一无所知。在那里定义的一组特性(然后被选择用于编译)被简单地转换为 rustc 调用的 --cfg 参数:rustc 不会知道任何存在但未启用的特性,Cargo 也不会使用 feature作为 rustc 特殊的任何方式的 cfg 密钥。
  • 没错,这就是为什么cargo 如果能够接受功能标志进行严格检查,会将标志传递给rustc
  • 在我看来,这是构建工具的特性,而不是 rustc 本身。不同的构建工具可能使用option 作为cfg 标识符而不是feature;可能会为每个此类功能提供其自己的 cfg 标识符,每个标识符都有一个布尔值(以指示它是否已启用);或者确实可能会做一些完全不同的事情。要求编译器为每个可能的构建工具提供一个验证器似乎是不必要的复杂,还有其他任何东西都会将它与一种特定的方法耦合得太紧吗?

标签: rust macros rust-cargo conditional-compilation


【解决方案1】:

RFC 3013,“在编译时检查条件编译”被实现时,#[cfg] 会出现警告,它引用了 Cargo 未声明的功能名称,正如您所要求的那样。但是,the implementation only just got started(2021 年 9 月 28 日)。

RFC 中描述的操作方式正如您所建议的那样,“cargo 会将标志传递给rustc”。


值得注意的是,这不会检查源文本中出现的所有条件;如in the RFC所述:

此 lint 将无法检测到未编译模块中的无效 #[cfg] 测试,可能是因为禁用了祖先模块。

因此,它不会确认所有 #[cfg(feature)] 在单个 cargo check 上都有效 — 您需要使用各种功能或功能组合进行测试。但是这些组合是您无论如何都需要检查所有可以启用的常规源代码中的编译错误的组合;一旦你这样做了,lint 将向你保证你没有任何#[cfg(feature)] 由于输入错误而从未启用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 2017-03-10
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    相关资源
    最近更新 更多