从 Rust 1.63(下周发布)开始,“非词法生命周期”(NLL)工作将默认启用。NLL 是 Rust 借用检查器的第二次迭代。该 RFC 实际上很好地突出了其中一些激励示例。“但是,”我听到你说,“NLL 不是包含在 Rust 2018 中吗?”是的,是的!但在那个时候,NLL 仅针对 Rust 2018 代码启用,而 Rust 2015 代码则在“迁移模式”下运行。在“迁移模式”下,编译器将运行旧的 *和* 新的借用检查器并比较结果。这样,我们可以对以前不应该编译的旧代码发出警告;我们还可以限制新代码中任何错误的影响。随着时间的推移,我们将迁移模式限制得越来越接近仅运行新式借用检查器:在下一个版本中,该过程将完成,所有 Rust 代码都将使用 NLL 进行检查。
删除旧借用检查器会如何影响用户?
在这一点上,我们几乎完全合并了“迁移模式”和“常规模式”,因此切换到 NLL 对用户体验的影响非常小。许多诊断都发生了变化,大多数都是为了更好——Jack Huey 在他的博客文章中提供了完整的详细信息。
功劳归功于
删除旧借用检查器的工作已经进行了多年。这是一个漫长、乏味且基本上毫无感谢的过程。我们想花点时间重点介绍参与的各个人员,并确保他们因自己的辛勤工作而得到认可
- Jack Huey (赞助页面),负责推动稳定的最终细节(诊断、协调行为差异)。
- Élie Roudninski,负责重构诊断代码并与 Jack 一起进行细致的工作(逐一检查每个回归案例)。
- Aaron Hill,为使 NLL 诊断达到标准做出了许多改进。
- Matthew Jasper,负责协调围绕高阶生命周期的错误和其他核心诊断改进。
- Rémy Rakic,负责重新构建 Matthew 的 PR 以及进行其他独立的诊断工作。
- Christopher Vittal,负责删除“比较”模式(不要问)。
- Centril,负责在早期进行大量工作来协调迁移模式和常规模式。
- 当然还有 NLL 工作组的成员(我自己、Felix Klock、Santiago Pastorino (赞助页面)、Matthew Jasper、David Wood、Rémy Rakic、Paul Daniel Faria、Nick Nethercote),他们首先交付了该功能。
Jack 的博客文章包含一个 详细的叙述,如果您想了解更多信息,可以阅读!这是一篇有趣的文章。
展望未来:我们对“未来的借用检查器”有什么期待?
Rust 借用检查的下一个前沿是采用 polonius 项目,并将其从研究实验转变为生产代码。Polonius 是借用检查器的下一代版本,它在 2018 年从主要的 NLL 工作中“分离”出来,因为我们正在准备将 NLL 推向生产。它最重要的贡献是修复了借用检查器的已知限制,以下示例证明了这一点
fn last_or_push<'a>(vec: &'a mut Vec<String>) -> &'a String {
if let Some(s) = vec.last() { // borrows vec
// returning s here forces vec to be borrowed
// for the rest of the function, even though it
// shouldn't have to be
return s;
}
// Because vec is borrowed, this call to vec.push gives
// an error!
vec.push("".to_string()); // ERROR
vec.last().unwrap()
}
此示例今天无法编译 (亲自尝试),尽管没有充分的理由。您通常可以通过编辑代码来引入冗余的 let
(如本示例所示) 来解决此问题,但使用 polonius,它将按原样编译。如果您想了解有关 polonius(以及现有借用检查器)的工作原理的更多信息1,您可以 观看我在 Rust Belt Rust 上的演讲。
-
或者“polonius”这个名字的由来! ↩