news 2026/10/16 6:02:48

Rust RFC 2834 深度解读:Cargo 未来不兼容(Future Incompatibility)报告机制的设计与实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Rust RFC 2834 深度解读:Cargo 未来不兼容(Future Incompatibility)报告机制的设计与实战
  • 文档

【免费下载链接】rfcs

RFCs for changes to Rust

项目地址:https://gitcode.com/gh_mirrors/rf/rfcs
点击查看免费下载

本指南围绕已合并进 RFC 仓库的 RFC 2834(对应实现追踪于 rust-lang/rust#71249)展开,系统讲解 Cargo 如何在构建结束阶段向开发者汇报上游依赖中触发"未来不兼容(future-incompatibility)"警告的 crate,即使这些警告已被--cap-lints=allow或#[allow(..)]抑制。读完本文,你将掌握该机制要解决的问题、rustc与 Cargo 的职责边界、构建结束报告的完整形态与cargo describe-future-incompatibilities的用法,以及.cargo/config中报告频率控制配置的设计思路,并理解其与仓库内相关 RFC 的演进关系。

背景:cap-lints机制及其副作用

要理解 RFC 2834,必须先理解它要对抗的机制——--cap-lints。仓库中的 RFC 1193 "cap-lints" 定义了该标志:

--cap-lints LEVEL设置本次编译的最高 lint 等级,不能被其他标志或属性覆盖。

其可接受值为allow、warn、deny、forbid。当传入--cap-lints allow时,源码中所有#[warn]、#[deny]、#[forbid]都会被忽略;传入--cap-lints warn时,只有deny和forbid指令被忽略。

RFC 1193 同时规定 Cargo 在编译所有上游依赖(非 path 依赖)时一律传入--cap-lints allow。这样做的理由很充分:如果上游 crate 使用了#![deny(warnings)],而新版本 Rust 引入了新的警告,上游依赖就可能编译失败,形成隐式破坏性变更。将上游依赖的 lint 封顶,可以让编译器在向后兼容的前提下自由演进 lint 集合。

然而副作用也随之而来:未来不兼容(future-incompatibility)lints 同样被cap-lints抑制了。这类 lint 标记的是一段"计划在未来的某个 Rust 版本中被移除/变成硬错误"的代码模式,通常涉及可能产生未定义行为(unsound)或语义未明确定义的构造。它们恰恰是开发者最需要提前知道的信号——因为一旦对应版本发布,整个项目将直接编译失败。

核心问题:下游维护者被蒙在鼓里

RFC 2834 引用了 rust-lang/rust#34596 中的一段经典描述:

如果你编写了一个被广泛使用的库,但当下并未积极使用它,你可能注意不到它将来会坏掉——而且,你的用户也不会注意到,因为 Cargo 在把你的库作为依赖编译时会封顶 lints。

运行示例:unwary与brash

RFC 用一对虚构 crate 说明问题:unwary依赖上游 cratebrash,而brash的源码触发了未来不兼容 lint——对 packed 字段的借用&x.data.0(即"safe packed borrows"问题,见 rust-lang/rust#46043)。

今天的实际行为如下:由于brash是unwary的非 path 依赖,构建unwary时 Cargo 会给rustc传入--cap-lints=allow,从而在诊断输出中完全抑制brash的警告:

crates % cd unwary unwary % cargo build # no warning issued about problem in the `brash` dependency. Compiling brash v0.1.0 Compiling unwary v0.1.0 (/tmp/unwary) Finished dev [unoptimized + debuginfo] target(s) in 0.30s unwary % cd ../brash brash % cargo build # (but a `brash` developer will see it when they build.) Compiling brash v0.1.0 (/tmp/brash) warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) --> src/lib.rs:13:9 | 13 | let y = &x.data.0; | ^^^^^^^^^ | = note: `#[warn(safe_packed_borrows)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043> = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior Finished dev [unoptimized + debuginfo] target(s) in 0.30s brash %

也就是说:brash的维护者自己构建时能看到警告,但unwary的维护者构建项目时看不到任何提示——直到某个未来的 Rust 版本发布,unwary直接编译失败。

反馈不能只是原始诊断输出

RFC 特别强调:反馈不应仅仅是brash的原始诊断输出。unwary的维护者在短期内通常无法对上游 crate 的警告做任何事(可以向brash提 issue 甚至贡献修复代码,但在brash发布新版本之前,这并不能解决眼前的问题)。因此,如果 Cargo 直接把上游的诊断一股脑铺在终端里,对unwary的维护者而言只是噪音。

正确做法是:继续对上游依赖传递--cap-lints=allow,同时让rustc通过某种渠道告诉 Cargo"哪些 crate 触发了未来不兼容 lint",再由 Cargo 在构建结束时给出简洁的汇总报告。

提案总览:保留 cap-lints,增加汇总报告

RFC 2834 的设计目标可以概括为三条:

  1. 继续传递--cap-lints=allow:非 path 上游依赖的正常 lint 仍被封顶,不改变既有行为。
  2. rustc上报触发信号:即使警告被抑制,rustc也要通过某种通道告知 Cargo 未来不兼容 lint 被触发了。
  3. cargo汇总反馈:在构建结束时输出一份精炼报告,列出哪些 crate 包含未来会被拒绝的代码,并(可选)给出解决建议。

RFC 还设想 Cargo 可以额外提供解决策略的反馈,例如:

  • 查询本地 index:看上游 crate 是否有更新版本可用,若有则建议用户通过cargo update升级(这只是一种启发式手段,并不会预先验证新版本是否真的解决了问题;若 Cargo 未运行在 offline 模式,也可进一步查询 crates.io 本身,但查询 index 在实践中通常已足够);
  • 建议提交 bug:提示unwary维护者到上游 crate 的源码仓库提交或搜索已归档的 issue(brash作者可能自己都不知道这个问题——例如他在该 lint 随编译器发布之前就停止了维护);
  • 标注截止时间:rustc为每个未来不兼容 lint 内嵌"距离变成硬错误还有多久"的信息,让维护者知道还有多少时间窗口去推动上游修复或更换 fork。

这些建议的具体形式不在 RFC 的强制范围内,详见后文"未来可能性"一节。

用户视角:构建结束时的报告形态

什么是"未来不兼容"

RFC 给出的定义:未来不兼容(future incompatibility)是指计划在未来某个 Rust 版本中从语言中移除的代码模式。这类模式通常是无未定义行为但语义未完全定义、或确实 unsound 的构造,但因为被广泛使用,需要一段宽限期再移除。

构建结束报告

在 Cargo 完成一个 crate 及其上游依赖的编译后,如果任何 crate(或其上游依赖)触发了未来不兼容警告、且整体编译没有错误,Cargo 会在编译结束阶段列出所有触发该警告的 crate;可能时,报告还会包含预计 Rust 停止编译该代码的未来日期或版本号:

crates % cd unwary unwary % cargo build Compiling brash v0.1.0 Compiling bold v0.1.0 Compiling rash v0.1.0 Compiling unwary v0.1.0 Finished dev [unoptimized + debuginfo] target(s) in 0.30s warning: the crates brash, bold, and rash contain code that will be rejected by a future version of Rust. note: the crate rash will stop compiling in Rust 1.50 (scheduled for February 2021). note: to see what the problems were, invoke `cargo describe-future-incompatibilities` unwary %

注意这里报告的是crate 名级别的汇总,而非逐个表达式的诊断,这正是 RFC 刻意设计的"简洁"形态。

依赖图中的多重版本

如果当前 crate 的依赖图中存在同一 crate 的多个版本被列入了结束报告,那么结束报告应明确指出是哪个(或哪些)版本触发了 lint。这对cargo tree里常见的传递依赖版本分叉场景至关重要——维护者需要知道该去升级哪一条依赖链。

cargo describe-future-incompatibilities:查看详细诊断

报告末尾的 note 提示用户调用cargo describe-future-incompatibilities。该命令会让 Cargo 查询上一次构建缓存的信息,打印出更有信息量的诊断:

unary % cargo describe-future-incompatibilities The `brash` crate currently triggers a future incompatibility warning with Rust, with the following diagnostic: > warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) > --> src/lib.rs:12:9 > | > 12 | let y = &x.data.0; // UB, also future-compatibility warning > | ^^^^^^^^^ > | > = note: `#[warn(safe_packed_borrows)]` on by default > = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! > = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043> > = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior The `bold` crate currently triggers a future incompatibility warning with Rust, with the following diagnostic: > warning: private type `foo::m::S` in public interface (error E0446) > --> src/lib.rs:5:5 > | > 5 | pub fn f() -> S { S } > | ^^^^^^^^^^^^^^^^^^^^^ > | > = note: `#[warn(private_in_public)]` on by default > = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! > = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> The `rash` crate currently triggers a future incompatibility warning with Rust, with the following diagnostic: > error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions. > --> src/lib.rs:4:8 > | > 4 | fn bar<T=i32>(x: T) { } > | ^ > | > = note: `#[deny(invalid_type_param_default)]` on by default > = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! > = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>

这个"汇总报告 + 按需查看明细"的两级设计,让想搞清楚问题的开发者有路可循,又不会用他们本地开发用不上的信息淹没所有人的诊断输出。

重编译时报告仍会保留

即使上游依赖没有重新编译,重建unwary时结束报告依然会输出——因为 Cargo 会把未来不兼容状态缓存在target/目录中:

unwary % touch src/main.rs unwary % cargo build Compiling unwary v0.1.0 Finished dev [unoptimized + debuginfo] target(s) in 0.30s warning: the crates brash, bold, and rash contain code that will be rejected by a future version of Rust. note: the crate rash will stop compiling in Rust 1.50 (scheduled for February 2021). unwary % note: to see what the problems were, invoke `cargo describe-future-incompatibilities`

根 crate 自身触发时的一致性

为了用户体验一致,即使根 crate 自己是触发未来不兼容 lint 的唯一来源,Cargo 也应在结束阶段发出同样的警告(此时构建过程中的原始警告依然照常显示):

crates % cd brash brash % cargo build Compiling brash v0.1.0 (/tmp/brash) warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) --> src/lib.rs:13:9 | 13 | let y = &x.data.0; | ^^^^^^^^^ | = note: `#[warn(safe_packed_borrows)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043> = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior Finished dev [unoptimized + debuginfo] target(s) in 0.30s warning: the crate brash contains code that will be rejected by a future version of Rust. brash % cargo build Finished dev [unoptimized + debuginfo] target(s) in 0.00s warning: the crate brash contains code that will be rejected by a future version of Rust. note: to see what the problems were, invoke `cargo describe-future-incompatibilities` brash %

注意第二次构建(增量、无编译发生)依然输出了警告,印证了"报告依赖缓存、不依赖重建"的设计。

无警告时输出不变

如果没有任何未来不兼容警告,Cargo 的输出与今天完全一致。例如unwary升级了brash的版本、切换到bold2(bold的 fork)、并用本地代码替换了对rash的使用,从而消除了所有触发点:

crates % cd unwary unwary % cargo build Compiling brash v0.2.0 Compiling bold2 v0.1.0 Compiling unwary v0.2.0 Finished dev [unoptimized + debuginfo] target(s) in 0.30s unwary %

参考级设计:rustc与 Cargo 的职责划分

RFC 2834 的核心约束是最小化对现有 Rust 用户的干扰:正常 lint 检查继续被抑制,因此 Cargo 继续对非 path 上游依赖传递--cap-lints=allow。

-Dwarnings语义保持不变

与 lint 直接交互的标志(如-Dwarnings)行为不变。以unwary为例:

  • 无论是cargo rustc -- -Dwarnings还是RUSTFLAGS=-Dwarnings cargo build,每次rustc调用的方式都相同,产出的诊断集合也与今天一致;
  • 下游brash这个非 path 依赖中的警告 lint 依旧被 cap,其未来不兼容警告仍被隐藏;
  • Cargo 在构建结束时输出的"brash包含未来将被拒绝的代码"报告不是 lint,不与-Dwarnings交互;
  • 结论:即使你向rustc传了-Dwarnings,收到未来不兼容报告也不会导致构建失败。

rustc的职责

编译器侧的行为会有轻微变化:即使在--cap-lints=allow开启的情况下,rustc也需要让 Cargo 知道未来不兼容 lint 何时被触发。具体而言:

  • rustc必须把未来不兼容 lints(参见 PR #59658 "Minimum Lint Levels")与那些"永远只是警告"的普通 lints 区分开来;
  • rustc需要一种新的操作模式,RFC 称之为future-incompatibility checking mode(未来不兼容检查模式):
    • 在该模式下,无论是否设置了--cap-lints=allow,都要检查未来不兼容 lints 的触发;
    • 在该模式下,无论代码是否出现在#[allow(..)]属性作用域内,也要检查这类 lint;
    • 在该模式下,诊断本身的输出仍可按--cap-lints=allow或#[allow(..)]被静默——这些标志/注解的语义是"静默诊断报告",但不是"静默关于源码中存在 lint 触发实例的反馈";
    • 该模式旨在解决 rust-lang/rust#34596 的主体问题。

Cargo 的职责

  • 以启用未来不兼容检查模式的方式调用rustc——无论是否同时传递--cap-lints=allow;
  • 捕获检查模式产出的任何输出,并在整个构建结束时汇总;
  • 将每个 crate 的未来不兼容记录存储在target/目录某处,从而在后续重建根 crate 时无需重编译即可输出同样报告(RFC 指出这在今天是容易满足的约束:nightly 渠道的 Cargo 已经在本地缓存构建上游 path 依赖时产生的警告);
  • 向用户建议解决问题的途径,具体策略不由本 RFC 强制规定。

实现策略:借助 JSON 错误格式

RFC 认为最干净的实现方式是:让rustc把--error-format=json视作"应当为当前 crate 输出未来不兼容汇总报告"的信号——扩展rustc的 JSON 输出,加入一条记录本次编译触发过的未来不兼容 lint 的新记录。

选用 JSON 的好处在于:JSON 记录更易于扩展,可以稳健地承载"该 lint 何时变为硬错误"这类元数据。不过 RFC 并不强制这一选择,其他选项包括使用环境变量 opt-in 改变rustc输出,或让rustc把未来不兼容元数据写入文件系统。

不是所有未来不兼容 lint 都有明确的"变为硬错误"时间表。RFC 假设会通过某种方式为它们建立排期,并要求每个未来不兼容 lint 的元数据都应包含(若已知)其变为硬错误的预期 Rust 版本——这也是采用 JSON 诊断的另一层动机。

相关政策考量

RFC 指出:不应盲目地把所有 lint 都纳入这套机制——当前被归类为C-future-incompatibility的 lint 并非都适合此机制,这是相关团队的政策决策,具体形态不在 RFC 范围内。

无论政策形式如何,有一点值得注意:遇到上游未来不兼容问题的用户,可能既没有空闲时间也没有外部开发资源。rustc开发者需要谨慎决定何时让某个 lint 开始通过该机制上报:

  • 如果首要目标是最大程度减少用户对工具和生态的挫败感,那么某个 lint 的未来不兼容上报应等到生态中大部分 crate 都已发布修复版本之后再开启;
  • 换句话说,应当追求一种稳态:典型用户面对未来不兼容报告时的反应,是运行cargo update,或请求合并一个(已存在的)PR。

频率控制:.cargo/config的future_incompatibility_report配置

"每次构建都提醒"对某些用户可能过于打扰——短期无法解决被标记的问题是很常见的。因此 RFC 提议扩展.cargo/config文件,让用户微调 Cargo 打印报告的频率。完整的提议配置如下:

[future_incompatibility_report] # This setting can be used to reduce the frequency with which Cargo will report # future incompatibility issues. # # The possible values are: # * "always" (default): always emit the report if any future incompatibility # lint fires, # * "never": never emit the report, # * "post-cargo-update": emit the report the first time we encounter a given # future incompatibility lint after the most recent # `cargo update` run for a crate, # * "daily": emit the report the first time any particular lint fires each day, # * "weekly": emit the report the first time any particular lint fires # each week (starting from Monday, following ISO 8601), # * "lunar": emit the report the first time any particular lint fires every # four weeks. (We recommend using this value in tandem with # an IDE that presents the current phase of the moon in its UI.) frequency = "always" # This allows a further fine-tuning for lints that have been given an # explicit schedule for when they will be turned into hard errors. # # If false, such scheduled lints are treated the same as unscheduled ones. # # If true, such scheduled lints issue their report more frequently # as time marches towards the release date when the warning becomes an error. # # Specifically, # * 6 weeks before that release, the report is emitted at least once per week, # * 2 weeks before that release, the report is emitted on every build. # # (Note that a consequence of the above definition, this value of this setting # has no effect if the `future_incompat_report_frequency` is "always".) telescoping_schedule = true

逐项解读:

  • frequency:可选值为"always"(默认,只要有未来不兼容 lint 触发就报告)、"never"(永不报告)、"post-cargo-update"(自最近一次对该 crate 执行cargo update之后,首次遇到某个未来不兼容 lint 时报告一次)、"daily"(每个 lint 每天首次触发时报告)、"weekly"(每周首次触发时报告,从周一开始,遵循 ISO 8601)、"lunar"(每四周首次触发时报告,RFC 调侃建议配合一个能显示月相的 IDE 使用);
  • telescoping_schedule:针对有明确"变为硬错误"排期的 lints 进一步微调。为false时,有排期的 lint 与无排期的同等对待;为true时,随着发布日临近报告越发频繁——发布前 6 周起至少每周报告一次,发布前 2 周起每次构建都报告。注意:当frequency = "always"时该设置不产生额外效果。

RFC 明确表示:它并不真正规定上述键值集合,而是信任 Cargo 团队来确定向用户暴露哪些合适的旋钮。这种"设计授权"也让最终实现可能与 RFC 文字略有出入。

缺陷与权衡(Drawbacks)

  • 该变更同时要求修改rustc和cargo,两者协调可能比较棘手;
  • RFC 建议的松耦合方式是"使用--error-format=json即启用未来不兼容检查模式",这避免了给rustc增加新的稳定命令行标志;但任何使用--error-format=json的非 Cargo 客户端,可能觉得这是编译器语义上令人困惑的变化。

备选方案辨析(Rationale and alternatives)

"不做改变"可行吗?

有人认为"现有做法一直在工作,无需改变"。RFC 的反驳是:之所以至今没爆发,恰恰是因为编译器和语言团队在把现有未来不兼容 lint 转为硬错误时被迫非常保守——这种转变成本极高,而这在很大程度上正是本 RFC 要解决的那个问题。在少数已经转为硬错误的案例中,团队花费了大量时间用 crater 评估破坏面并逐一修复。本 RFC 的变更希望能鼓励编译器/语言团队之外的更多 Rust 用户主动处理未来不兼容的破坏。

能否仅靠 Cargo 实现?

一种思路是不改rustc、把实现完全隔离在 Cargo 内:停止传--cap-lints=allow,让 Cargo 捕获编译器的全部诊断输出并事后处理、判断哪些 lint 是未来不兼容警告。但这有三大问题:

  1. 脆弱:依赖 Cargo 事后处理编译器的诊断输出;
  2. 低效:编译器现在必须为 crate 的所有依赖运行全部 lint 检查,而我们只关心其中一小部分;
  3. 不足:它只能处理--cap-lints的场景,无法捕捉上游依赖在源码中用#[allow(..)]属性规避警告的情况——而如果为了弥补这点去无条件改变rustc、让它无论--cap-lints=allow还是#[allow(..)]都输出未来不兼容反馈,又会惹恼那些期望这些标志/注解让诊断输出保持安静的人(也就是"编译器不听我的!")。这正是 RFC 坚持"--cap-lints=allow与#[allow(..)]继续静默诊断报告、仅把反馈限定为一句'crate brash 包含未来会被拒绝的代码'"的原因。

能否仅靠 rustc 实现?

PR #59658 "Minimum Lint Levels" 曾尝试在编译器内单独解决,做法是把未来不兼容 lint 标记为特殊情形、使其不受--cap-lints和#[allow(..)]静默。该 PR 的讨论列举了诸多问题,本质上是担心下游开发者被自己无能为力的 lints 刷屏。讨论的结论是:可以重做以降低刷屏——对每个依赖只报告 lint 的一次实例(而非该依赖中每个触发该 lint 的表达式各一条诊断)。这确实是改进,但仍不是理想体验。本 RFC 刻意把未来不兼容 lint 触发视为独立于普通诊断的严肃事件,值得 Cargo 特殊对待(甚至可能在线查询该 crate 是否有新版本)。注意:最低 lint 等级机制与本 RFC 不冲突,可以并行推进,只是它不足以单独解决眼前的问题。

扩展cap-lints层级是否更好?

另一个低影响方案是扩展--cap-lints的层级,使其变成:

allow warn-future-incompat warn deny-future-incompat deny

这样--cap-lints=warn-future-incompat表示"允许(不警告)所有非未来不兼容 lint,仅对未来不兼容 lint 警告";--cap-lints=deny-future-incompat表示"对非未来不兼容 lint 警告、对未来不兼容 lint 报错"。并且(关键一步)把cargo build的默认值改为cap-lints=warn-future-incompat,让开发者默认就能直接得知依赖中的未来不兼容。

RFC 作者选择不采用该方案,因为怀疑它会遭遇与"minimum lint levels"相同的困境:抛出一堆开发者无法立即在本地解决的诊断。(不过它仍可能是值得加入rustc和cargo的合理功能。)

未解决的问题

  • Cargo 自身发出的未来不兼容警告(如 rust-lang/cargo#6313 评论中所讨论的)应当被纳入支持,作者设想这不需要太多额外工作,但未明确处理也未深入调研;
  • 实现层面的问题:用--error-format=json作为把rustc切换进未来不兼容检查模式的方式是否合理?一个变体是改用--json CONFIG选项让 Cargo opt-in 该功能——这样已经使用--error-format=json的客户端就无需感知这一变化。

未来可能性:Cargo 给出的修复建议

RFC 设想的主要后续工作是 Cargo 围绕问题给出的反馈建议,列举了两种形态。

查询 crate 的新版/替代版本

当 crate 触发未来不兼容警告时,Cargo 可以到 crates.io 上查找该依赖的更新版本:

crates % cd unwary unwary % cargo build Compiling brash v0.1.0 Compiling bold v0.1.0 Compiling rash v0.1.0 Compiling unwary v0.1.0 Finished dev [unoptimized + debuginfo] target(s) in 0.30s warning: the crates brash, bold, and rash contain code that will be rejected by a future version of Rust. note: the crate rash will stop compiling in Rust 1.50 (scheduled for February 2021). note: newer versions of bold and rash are available; upgrading to them via `cargo update` may resolve their problems. unwary %

该建议目前只覆盖"升级到新版本"。若得到 crates.io 的更多帮助,还可以走得更远:建议用户切换到的上游 crate 的潜在 fork——这对处理 abandoned(无人维护)的 crate 很有用。

建议提交 bug report

如果没有更新版本可用,Cargo 可以输出一份用户可提交给上游 crate 的 bug report 模板:

crates % cd unwary unwary % cargo build Compiling brash v0.1.0 Compiling unwary v0.1.0 Finished dev [unoptimized + debuginfo] target(s) in 0.30s warning: the crate brash contains code that will be rejected by a future version of Rust. note: the following gist contains a bug report you might consider filing with the maintainer of brash. https://gist.github.com/pnkfelix/ae03d3ea95160fb71a797b15e05f8d49 unwary %

示例中模板被发布到 gist(使用作者自己的 GitHub 账号;RFC 坦言不确定能否让 Cargo 以匿名方式创建 gist,但应该能找到某种 pastebin 服务)。该模板的正文大致是:

这个 crate 目前触发了 Rust 的未来不兼容警告。 在 src/lib.rs:13:9 处有以下代码:let y = &x.data.0;这导致rustc发出如下诊断(来自 https://github.com/rust-lang/rust/issues/46043):warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133) ...由于该构造未来会变成硬错误,我们应该消除它的出现。

进一步细化:如果开始建议 bug report 模板,Cargo 或许还能在上游 crate 仓库中搜索与该模板描述匹配的既有 issue,并建议用户去查看其当前状态,而不是新开一个 issue——这样可以避免给上游维护者添麻烦。

与仓库其他 RFC 的关联

  • RFC 1193 cap-lints:本 RFC 的基石。--cap-lints标志与"Cargo 对上游依赖传--cap-lints allow"的约定,正是导致上游未来不兼容警告被隐藏的根源,也是 RFC 2834 选择继续保留的机制;
  • RFC 1589 rustc-bug-fix-procedure:展示了rustc侧如何注册未来不兼容 lint——通过store.register_future_incompatible(sess, vec![FutureIncompatibleInfo { id: LintId::of(..), reference: "issue #...." }])把 lint 标记为FutureIncompatibleInfo。这正对应本 RFC 中"rustc必须区分未来不兼容 lints 与其他 lints"的职责要求;
  • RFC 3389 manifest lint:其 Drawbacks 一节明确指出[lints]只影响关联包本身、不作用于依赖,因此无法与"针对依赖的未来不兼容 lints"协同工作,可能造成用户困惑——这从侧面印证了 RFC 2834 这类依赖级报告机制的必要性;
  • RFC 3874 与 RFC 3875:均提及cargo report(RFC 2834 所述机制落地后的命令形态)不会包含标准库 crate 及其依赖的报告,说明这套报告机制在现代 Cargo 中已与 build-std 场景做了明确隔离。

小结

RFC 2834 为 Rust 生态解决了一个隐蔽而危险的"定时炸弹"问题:上游依赖中的未来不兼容代码因cap-lints而被无声容忍,直到某个 Rust 版本发布时项目猝然编译失败。它给出的答案是职责分离——rustc以 JSON 错误格式承载未来不兼容检查模式的信号,Cargo 负责汇总、缓存(target/目录)与频率控制(.cargo/config),并把详细的逐 crate 诊断留给按需调用的cargo describe-future-incompatibilities。对于下游维护者,这套设计把"知道问题存在"与"不被原始诊断刷屏"两件事同时做到了。

  • 文档

【免费下载链接】rfcs

RFCs for changes to Rust

项目地址:https://gitcode.com/gh_mirrors/rf/rfcs
点击查看免费下载
上一篇:BiliTools:3分钟学会用这款开源工具箱管理你的B站收藏
下一篇:Cytoscape.js 集合过滤实战:eles.filter() 选择器与函数两种过滤方式的完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 6:00:13

2026年2月4日文登潮汐表解读:赶海黄金窗口与安全指南

赶海这事儿&#xff0c;最怕的不是风浪&#xff0c;是没算准潮。2026年2月4日&#xff0c;农历腊月十七&#xff0c;正好卡在立春前后&#xff0c;又是望汛刚过&#xff0c;文登沿海的潮差会明显拉大。如果这一天你打算去五垒岛湾、南海新区或者小观、泽库一带的海滩&#xff0…

作者头像 李华
网站建设 2026/10/16 5:59:47

Windows下Python 3.6安装Mayavi:whl依赖与报错排查全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 5:55:50

REA 重构就绪检查:为什么缺失证据必须报告 unknown 而不是 pass

REA 重构就绪检查&#xff1a;为什么缺失证据必须报告 unknown 而不是 pass 【免费下载链接】rea Reverse engineer anything with agents, from app behavior down to native binaries. 项目地址: https://gitcode.com/GitHub_Trending/rea2/rea 大多数就绪性检查都会做…

作者头像 李华
网站建设 2026/10/16 5:53:59

Java与大数据学习路线:四阶段能力组装施工图

1. 这不是一张“万能地图”&#xff0c;而是一份踩过坑后画出的施工图“Java及大数据学习路线”——这七个字在招聘网站、技术社区、自学论坛里高频出现&#xff0c;但凡想转行进开发、想从传统后端往数据方向拓展、或者刚毕业不知该往哪扎的新人&#xff0c;几乎都会搜它。可搜…

作者头像 李华