前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rust 1.52.1 已正式发布,及其新特性详述—重要,官方建议升级

Rust 1.52.1 已正式发布,及其新特性详述—重要,官方建议升级

作者头像
niqin.com
发布2022-09-01 15:42:29
9470
发布2022-09-01 15:42:29
举报
文章被收录于专栏:Rust 生态与实践Rust 生态与实践

2021 年 5 月 10 日,Felix Klock 和 Mark Rousskov 代表 Rust 编译器团队发布文章 Announcing Rust 1.52.1,官宣发布 Rust 1.52.1。

以下为官方公告原文——

Rust 团队新发布的 Rust 1.52.1,解决了一个增量编译中的 bug,这个 bug 在 1.52.0 中,会导致一个编译器错误。我们建议所有 Rust 用户(包括使用 1.52.0 及之前稳定版本的用户)升级到 1.52.1,或者也可以禁用增量编译。如下是升级指导。

如果你已通过 rustup 安装了 Rust 的早期版本,那么更新到 Rust 1.52.1 相当容易:

代码语言:javascript
复制
rustup update stable

如果您还未安装过 Rust,可以从 Rust 官网页面获取 rustup

如果官方途径安装速度较慢,可以配置 Rust 工具链的国内源,请参阅《配置 Rust 工具链的国内源》。

概要说明

此次发布,是针对 1.52.0 版本上的问题构建的,这些问题因新添加的验测而起。此次验测工作检测到的 bug,存在于 Rust 1.24 之后的版本中(因为增量编译是自 Rust 1.24 启用)。并且可能触发增量构建中的错误编译,因此降级到以前的稳定版本,并非解决方案。

因此,建议所有用户升级到 1.52.1,或在本地环境中禁用增量(如果使用 1.52.0 及之前版本):有关如何禁用增量的详细信息,请参阅小节:Rust 程序员该做的事情。

增量编译,在缺省情况下是关闭的,因此很少有生产环境的构建会受到影响(仅对选择启用的用户有影响)。

增量编译中的错误,可能会导致错误的编译!从而在最终的工件中,生成不正确的代码,既是会生成格式错误的二进制文件。这意味着,理论上,任何行为都是可能的。在实践中,我们目前只发现了一个特定的已知错误,但由于增量错误是出了名的难以追踪:如果用户从二进制文件中看到意外的结果,他们通常会在进行轻度重构后重新构建。这时,通常会进行充分的重新编译,可以修复错误。

本篇文章的目的是:

  1. 解释错误的具体表征;
  2. 在高层次上,解释检查(check)的作用;
  3. 解释 Rust 1.52.0 中,检查的具体展现;
  4. 在你的项目上,如果出现不稳定(unstable)的编译器指纹,告诉你如何做;
  5. 关于此问题,描述 Rust 团队的解决计划。

错误的具体表征?

错误消息是类似于这样的展现,关键部分文本是:“found unstable fingerprints”。

代码语言:javascript
复制
thread 'rustc' panicked at 'assertion failed: `(left == right)`
  left: `Some(Fingerprint(4565771098143344972, 7869445775526300234))`,
  right: `Some(Fingerprint(14934403843752251060, 623484215826468126))`: found unstable fingerprints for <massive text describing rustc internals elided>

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

这是内部一致性检查导致的错误,如诊断中所述,它会产生“内部编译器错误”,也称作 ICE。换句话说,它代表了 Rust 编译器内部的一个 bug。具体在本例中,既是 ICE 揭示了关于增量编译的一个 bug。在早于 1.52.0 的版本中,或许没有捕获到它,但可能会导致错误编译。

什么是编译器指纹(fingerprints),为什么我们要对其检查?

Rust 编译器支持“增量编译”,在 2016 年的博客文章中,对有描述。当增量式编译开启时,编译器会将输入源分割成多个片段,并追踪这些输入片段如何影响最终的构建产品。然后,当输入发生变化时,它会检测到这一点并重用以前构建的工件,努力让构建需要的响应输入,仅在源代码发生变化的部分上花费精力。

编译器指纹(fingerprints)是我们体系结构的一部分,用来检测输入变化。更具体地说,编译器指纹(fingerprints,以及建立上下文的一些其它状态)是一个 128 位的值,用于唯一标识编译器中使用的内部值。某些编译器内部结果,在运行时缓存(cached)在磁盘上。编译器指纹(fingerprints)用于验证新计算的结果,是否与缓存的结果相同(有关这方面的详细信息,请参阅《rustc 开发指南》的相关章节)。

编译器指纹(fingerprints)的稳定性检查,是维护编译器指纹(fingerprints)内部一致性的保障措施。有时,编译器被迫重新运行检查,并期望输出与以前会话的增量编译输出相同。新启用的验证,将检查该值是否确实如预期的那样,而不是假设是这样。但在某些情况下,由于编译器实现中的错误,实际情况并非如此。

历史回溯

我们将编译器指纹(fingerprints)检查作为 rustc 开发工具的最初时间,是在 2017 年。它是作为一个不稳定的(unstable)标志 -Z 提供的,只对 nightly 版和开发版的构建可用。

最近,在 3 月份,我们遇到了一个错误编译,导致我们在默认情况下打开了 verify-ich。Rust 编译器团队认为:最好是捕获编译器指纹(fingerprints)问题并中止编译,而不是允许潜在的错误编译(以及随后的错误行为),以防止错误潜入二进制文件中。

当我们第一次默认开启编译器指纹(fingerprints)检查时,nightly 和 beta 版工具链的用户,会不断提交问题(issues),并且在修复方面也取得了稳步进展。其中一些已经解决。

上周,我们已经开始编制改善用户体验的计划,这样检查发出的诊断就可以更好地告诉程序员应该做什么。不幸的是,这样做的前提是:新的验证本将在 1.53 中发布,而非 1.52。

但最近发布的版本 Rust 1.52.0(请参阅 Rust 1.52.0 已正式发布,及其新特性详述),启用了 verify-ich

今天的新版本 Rust 1.52.1,解决了因新添加的验证而导致的问题。此版本中,临时将 Rust 编译器中的默认值更改为禁用增量编译,除非用户有意选择启用。

为什么会出现此问题?

从本质上讲,对于某些 crate,特定的编辑-编译(edit-compile)周期序列,将导致 rustc 遇到“不稳定指纹(unstable fingerprints)”的内部编译错误(ICE)。如文章开头展示的例子所示。

我们再来看看另一个例子的编译错误:

代码语言:javascript
复制
thread 'rustc' panicked at 'found unstable fingerprints for predicates_of(<massive text describing rustc internals elided>)', /rustc/.../compiler/rustc_query_system/src/query/plumbing.rs:593:5

它们具有相同原因,将存储在磁盘上的增量编译缓存与当前 rustc 调用期间计算的值进行比较时,出现了不一致情况。这意味着,它们都是由于使用增量编译造成的。

如下方法可以开启增量编译:

  1. 使用默认启用增量编译的 devtest 配置文件进行构建。
  2. 设置环境变量 CARGO_INCREMENTAL=1
  3. 设置 Cargo config 文件,启用 build.incremental
  4. 设置 Cargo.toml,启用 incremental

如果项目中没有调整默认值,那么当运行 cargo build --release 时,或在 release 配置文件中,所有 Rust 1.x 都将禁用增量编译。这些问题,不应该影响你的版本发布。

Rust 程序员该做的事情

如果你发生内部编译器错误,请你报告此 bug。我们仍然需要该方面的信息,想知道失败的案例。

但是,无论你是否提交 bug,你都可以通过以下方式解决问题:

  1. 升级到 1.52.1,将会为你禁用增量编译。或者
  2. 删除增量编译缓存(例如,运行 cargo clean),或者
  3. 通过在环境变量中设置 CARGO_INCREMENTAL=0,或在 config.toml 中指定 build.incrementalfalse,强制禁用增量编译。

我们推荐用户都将 1.52.0 升级为 to 1.52.1,这样做即可禁用增量编译。

我们不建议 Rust 1.52.0 的用户,为了应对这个问题而降级到 Rust 的早期版本。如上所述,至少有一个实例,由于增量编译导致了错误编译。在我们添加编译器指纹(fingerprints)检查之前,错误未被捕获。

Rust 1.52.1 的用户,如果希望自行处理增量验证的 ICE(译注:内部编译错误)问题,并希望选择返回版本 1.52.0。则可以在环境变量中,设置 RUSTC_FORCE_INCREMENTAL=1。如此,Rust 编译器将执行 Cargo 传递的选项 -Cincremental,尽管添加了验证,但仍将以前版本一样工作。请注意,Rust 1.52.1 中,如果此标志尚未单独启用(无论是通过 Cargo 还是其它方式),则不会启用增量。

如果你当前正在使用 1.52.0 之前的工具链,并且希望继续这样做,我们建议你禁用增量编译,以避免出现无提示的错误编译。

自从增量编译启用以来,在所有的 Rust 构建中,编译时间对许多用户来说,都是一个重大的改进,而且会随着时间的推移而逐步改进。我们承认,这里提出的解决办法和建议,多用户来说是痛苦的,我们将努力保证这只是暂时的解决方案。

Rust 团队如何解决此问题?

译注:计划方面,和上文多有重复,即是配置环境变量和设置指定文件的反复。所以未再详细翻译,所有翻译开源在 github.com/zzy/blog.rust-lang.org-zh-cn,欢迎你补充和完善。

短期计划

既是我们发布了此 1.52.1 版本。

长期计划

修复错误。

谢谢您的阅读,欢迎交流。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust 生态与实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概要说明
    • 错误的具体表征?
      • 什么是编译器指纹(fingerprints),为什么我们要对其检查?
        • 历史回溯
          • 为什么会出现此问题?
            • Rust 程序员该做的事情
              • Rust 团队如何解决此问题?
                • 短期计划
                • 长期计划
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档