从Rust 1.63(下周发布)开始,"非逻辑寿命"(NLL)工作将被默认启用。NLL是Rust的借贷检查器的第二次迭代。RFC实际上很好地强调了一些激励性的例子。"但是,"我听到你说,"NLL不是包含在Rust 2018中吗?" 是的,是的,它是!但在当时,NLL是在Rust2018中。但在当时,NLL只对Rust 2018的代码启用,而Rust 2015的代码则以 "迁移模式 "运行。当处于 "迁移模式 "时,编译器会同时运行新旧借款检查器并比较结果。这样一来,我们就可以对那些一开始就不应该编译的旧代码发出警告;我们也可以限制新代码中任何错误的影响。随着时间的推移,我们对迁移模式进行了限制,使其越来越接近于只运行新式的借贷检查器:在下一个版本中,这一过程已经完成,所有的Rust代码都将用NLL检查。
删除旧式借款检查器对用户有什么影响?
在这一点上,我们几乎完全合并了 "迁移模式 "和 "常规模式",所以切换到NLL对用户体验的影响非常小。一些诊断程序发生了变化,大多是为了更好的发展 --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),他们首先提供了这个功能。
如果你想了解更多细节,杰克的博客文章包括了对所有相关工作的详细叙述!这是一个有趣的阅读。这是一个有趣的阅读。
展望未来:我们能对 "未来的借款检查器 "有什么期待?
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()
}
这个例子今天不能编译(自己试试),虽然没有一个很好的理由。你通常可以通过编辑代码来解决这个问题,引入一个多余的if(如本例所示),但用polonius,它将按原样编译。如果你想了解更多关于polonius(以及现有的借贷检查器)的工作原理。