完成向新的借用检查器的过渡

2019 年 11 月 1 日 · Niko Matsakis

在 2018 年的大部分时间里,我们一直在发布关于借用检查器中各种错误的警告,我们计划修复这些错误——大约两个月前,在当前的 Rust nightly 版本中,这些警告变成了 **硬错误**。大约两周后,当 nightly 分支成为 beta 时,这些硬错误将出现在 beta 版本中,并最终在 12 月 19 日作为 Rust 1.40.0 的一部分出现在稳定版本中。**如果您正在使用 Nightly 进行测试,那么您应该一切正常——但除此之外,您可能需要检查一下您的代码是否仍然可以构建。如果没有,我们将在下面提供一些修复常见问题的建议。**

背景:非词法生命周期过渡

当我们 在 Rust 1.31 中发布 Rust 2018 时,它包含了一个新的借用检查器版本,该版本实现了 "非词法生命周期"。这个新的借用检查器比原来的检查器进行了更精确的分析,使我们能够消除许多不必要的错误,并使 Rust 更易于使用。我认为大多数使用 Rust 2015 的人都可以证明,这种转变是一个巨大的进步。

新的借用检查器还修复了许多错误

也许不太为人所知的是,新的借用检查器实现也修复了许多错误。换句话说,新的借用检查器不仅接受了更多程序——**它还拒绝了一些程序,这些程序最初之所以被接受,是因为旧的借用检查器中存在内存不安全错误!**

直到最近,这些修复的错误才会产生警告,而不是错误

显然,我们不想接受可能破坏 Rust 安全保证的程序。同时,作为我们对稳定性承诺的一部分,我们尽量避免进行突然的错误修复,这些修复会影响大量代码。只要有可能,我们更倾向于逐步“逐步引入”这些更改。例如,我们通常会先使用“未来兼容性警告”,然后再将这些警告转换为硬错误(有时一次一小部分)。由于借用检查器的错误修复影响了许多板条箱,我们知道在将它们转换为硬错误之前,我们需要一个警告期。

为了实现这个警告期,我们保留了两个借用检查器的副本(这实际上是我们经常使用的一个技巧)。新的检查器首先运行。如果它发现错误,我们不会直接报告它们:相反,我们会运行旧的检查器,以查看板条箱是否在之前编译过。如果是这样,我们会将这些错误报告为未来兼容性警告,因为我们正在改变一些以前可以编译成错误的东西。

所有美好的事物都必须结束;不好的事物也是如此

随着时间的推移,我们一直在逐步将这些未来兼容性警告转换为错误,一次一小部分。大约两个月前,我们决定是时候完成这项工作了。因此,在两个 PR 的过程中,我们 将所有剩余的警告转换为错误,然后 删除了旧的借用检查器实现

这对您意味着什么

**如果您正在使用 nightly 测试您的软件包,那么您应该没问题。**事实上,即使您在稳定版本上构建,我们也始终建议您在 CI 中使用 nightly 版本测试您的构建,以便您可以尽早识别即将出现的问题并向我们报告。

**否则,您可能需要检查您的依赖项。**当我们决定删除旧的借用检查器时,我们还分析了哪些板条箱将停止编译。对于任何似乎被广泛使用的板条箱,我们确保有更新版本的板条箱可用,这些板条箱可以编译(在大多数情况下,这在警告期间已经全部完成)。但是,如果您在 Cargo.lock 文件中拥有这些旧版本,并且您只使用稳定版本构建,那么您可能会发现您的代码在 1.40.0 发布后不再构建——您将不得不升级依赖项。

受影响最常见的板条箱如下

  • url 版本 1.7.0——您可以升级到 1.7.2,但最好升级到 2.1.0
  • nalgebra 版本 0.16.13——您可以升级到 0.16.14,但最好升级到 0.19.0
  • rusttype 版本 0.2.0 到 0.2.3——您可以升级到 0.2.4,但最好升级到 0.8.1

您可以使用 cargo-tree 命令找出您依赖的哪些板条箱。如果您发现您确实依赖(例如)url 1.7.0,您可以通过执行以下操作升级到 1.7.2

$ cargo update --package url --precise 1.7.2

想要了解更多?

如果您想了解更多关于修复的错误类型的信息——或者如果您在代码中看到需要修复的错误——请查看 Felix Klock 的这篇优秀的博客文章,它详细介绍了这些信息。