[建议升级] Rust 1.52.1 版本发布,解决了增量编译中的一个错误

596

Rust 1.52.1 发布,解决了解决了增量编译中的一个错误,以下来自 Rust 团队对于改问题的解释 & 改进计划的翻译,enjoy ( 原文:blog.rust-lang.org/2021/05/10/…

Rust团队准备了一个新的版本,1.52.1,解决了增量编译中的一个错误,这个错误在1.52.0中被做成了一个编译器错误。我们建议所有的Rust用户,包括目前使用1.52.0之前的稳定版本的用户,升级到1.52.1或禁用增量编译。关于如何做到这一点的指导意见见下文。

如果你已经通过 rustup 安装了以前 的Rust版本,获得 Rust 1.52.1 就很简单了:

rustup update stable

如果你还没有,你可以从我们网站上的相应页面获得rustup

摘要

这个版本解决了1.52.0中的构建问题,这是由新增加的验证引起的。这个验证所检测到的错误存在于所有的Rust版本1中,并可能在增量构建中引发错误编译,所以降级到之前的稳定版本并不是一种修复。

我们鼓励用户升级到1.52.1,如果是之前的版本,则在本地环境中禁用增量编译:关于如何做的细节,请参见what you should do章节。

发布版本的增量编译默认是关闭的,所以很少有生产版本会受到影响(只对选择了的用户)。

增量编译中的错误可能会在最终产品中产生不正确的代码,基本上会产生畸形的二进制文件,这意味着在理论上任何行为都是可能的。在实践中,我们目前只知道有一个特定的错误编译,但由于增量编译引起的错误是出了名的难以追踪:如果用户从他们的二进制文件中看到意外的结果,他们经常只是在一些简单的编辑后重建,这往往会导致足够的重新编译来修复这个错误。

这篇文章将。

  1. 解释这些错误是什么样子的。
  2. 解释检查的作用,在一个较高的水平上。
  3. 解释该检查在Rust 1.52.0版本中是如何呈现的。
  4. 告诉你,如果你在你的项目上看到不稳定的指纹,你应该怎么做
  5. 描述我们对Rust项目如何解决这里讨论的问题的计划。

这个错误是什么样子的?

错误信息看起来像这样,关键部分是 "发现不稳定的指纹 "的文字。

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编译器本身内部的一个错误。在_这种_情况下,ICE揭示了增量编译中的一个错误,这个错误在1.52.0版本之前就存在,如果没有被发现,可能会导致错误编译。

什么是指纹?我们为什么要检查它们?

Rust编译器支持 "增量编译",这在2016年的一篇博文中已有描述。当增量编译开启时,编译器会将输入源分成几块,并跟踪这些输入块如何影响最终的构建产品。然后,当输入发生变化时,它会检测到这一点,并重用以前构建的工件,努力将精力只花在构建需要响应输入源代码变化的部分。

指纹是我们检测输入变化的架构的一部分。更具体地说,指纹(与其他一些状态一起建立上下文)是一个128位的值,旨在唯一地识别编译器内使用的内部值。一些编译器内部的结果在运行期间被存储在磁盘上("缓存")。指纹被用来验证新计算的结果与缓存的结果没有变化。关于这一点的更多细节可以在ustc开发指南的相关章节中找到)。

指纹稳定性检查是断言指纹内部一致性的一种保障。有时编译器被迫重新运行一个查询,并期望输出与之前的增量编译会话相同。新启用的验证会检查该值是否确实与预期一致,而不是假设如此。在某些情况下,由于编译器实现中的错误,实际情况并非如此。

历史

我们最初在2017年这些指纹检查作为开发rustc本身时使用的工具。它只通过一个不稳定的-Z 标志提供,只适用于夜间和开发版本。

最近,在3月份,我们遇到了一个错误的编译,导致我们默认打开了verify-ich 。Rust编译器团队决定,与其让潜在的错误编译(以及随后的错误行为)潜入Rust程序员的二进制文件,不如抓住指纹问题并中止编译。

当我们第一次默认开启指纹检查时,有源源不断的问题由夜间(和测试版)工具链的用户提交,并且在识别修复方面取得了稳定的进展,其中有一些已经落地了。

在过去的一周里,我们已经开始计划改进用户体验,以便使检查所发出的诊断书能够更好地告诉程序员该做什么反应。不幸的是,这是在假设新的验证会在1.53版本出货,而不是1.52版本的情况下进行的。

事实证明,verify-ich 是在最近发布的1.52.0版本中开启的。

今天的新版本,1.52.1,通过暂时改变Rust编译器的默认值,禁用增量,除非用户有意选择,来解决新增加的验证造成的破坏。

这一点是如何表现出来的

基本上,对于某些板块来说,某些编辑-编译循环的序列会导致rustc ,以达到 "不稳定的指纹 "的ICE。我在这篇博文的开头展示了一个例子。

另一个最近的例子是这样的

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 配置中启用了build.incremental 设置
  4. 你可能在Cargo.toml中为某个配置文件启用了incremental 的设置。

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

Rust程序员应该如何应对

内部编译器错误要求你报告一个错误,如果你能这样做,我们仍然希望得到这些信息。我们_想_知道那些失败的案例。

但是,无论你是否提交了一个bug,这个问题都可以通过以下两种方式在你这边解决。

  1. 升级到1.52.1,如果你还没有这么做的话(这将使你的增量功能失效),或
  2. 删除你的增量编译缓存(例如,通过运行cargo clean ),或者
  3. 通过在你的环境中设置CARGO_INCREMENTAL=0 或在build.incrementalfalse config.toml 强制禁用增量编译。

我们建议 1.52.0 的用户升级到 1.52.1,它可以禁用增量编译。

我们_不_建议1.52.0的用户为了应对这个问题而降级到早期的Rust版本。如上所述,至少有一个由增量编译引起的无声错误编译的例子,在我们添加指纹检查之前没有被发现。

如果用户愿意处理增量验证ICE的问题,并希望选择回到1.52.0的行为,他们可以在他们的环境中把RUSTC_FORCE_INCREMENTAL1 。这样Rust编译器就会尊重Cargo传递的-Cincremental 选项,事情就会像以前一样进行,不过会增加验证。请注意,如果没有单独启用增量,这个标志不会启用增量(无论是由Cargo还是其他方式)。

如果你正在使用1.52.0之前的工具链,并且希望继续这样做,我们建议你禁用增量编译,以避免遇到沉默的错误编译。

在增量编译登陆后的所有Rust版本中,它对许多用户的编译时间都有很大的改善,而且随着时间的推移,这种改善只会越来越大。我们承认这里提出的变通方法和建议是痛苦的,并将努力确保这种情况尽可能是暂时的。

Rust项目要做什么来解决这个问题

短期计划

我们今天发布了1.52.1,该版本。

  • 禁用Rust编译器中的增量编译(除非由一个新的环境变量要求,RUSTC_FORCE_INCREMENTAL=1 )。
  • 如果启用了增量编译,改进了新验证的诊断输出,指出如何通过清除增量状态或禁用增量来解决这些错误。

这旨在成为一种缓解措施,帮助大多数Rust用户拥有升级到安全的Rust编译器的路径,这种编译器不会有错误编译他们代码的风险,但也为愿意处理错误的用户提供了选择。

我们希望继续积极投资修复这些错误,并且根据我们对修复的信心,可能会发布一个1.52.2点版本,将这些修复移植到稳定频道。希望帮助我们测试的用户可以使用夜间频道,并向rust-lang/rust报告他们看到的任何ICE的错误。

我们目前也不打算在测试频道上禁用增量,但这个决定还没有得到坚定的承诺。今天在1.53测试版上有一些修复,所以希望继续使用增量的用户可能想切换到这个版本。当然,Nightly将永远有最新的修正。

长期计划

长期计划是修复bug!增量编译是Rust编译器能够为所有程序员提供快速编辑-编译-运行周期的唯一现实途径,因此我们需要通过verify-ich ,解决迄今为止已经发现的所有问题。到目前为止,共有32个这样的问题,尽管很多是重复的)。

我们正在积极地投资于此,一些错误已经被发现并修复。根据修复的情况,未来的稳定版(1.53及以后)将可能重新启用增量编译。

Rust团队还将制定计划,以确保我们在未来有更好的错误跟踪系统,这既是为了防止类似的情况再次出现,也是为了在错误跨渠道传播时更准确地跟踪它们,从而进一步提高我们发布版本的稳定性。

自增量首次启用以来,也就是在Rust 1.24中。