发布 Rust 1.41.1

2020年2月27日 · Rust 发布团队

Rust 团队发布了 Rust 的一个新的点版本,1.41.1。Rust 是一门赋予每个人构建可靠且高效软件能力的编程语言。

如果你之前通过 rustup 安装了 Rust,那么获取 Rust 1.41.1 非常简单,只需运行

$ rustup update stable

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

1.41.1 stable 版本包含什么?

Rust 1.41.1 解决了 Rust 1.41.0 中引入的两个关键回归问题:一个与 static 生命周期相关的健全性漏洞,以及一个导致段错误的错误编译。这些回归问题不影响更早的 Rust 版本,我们建议 Rust 1.41.0 用户尽快升级。此版本还解决了另一个可追溯到 Rust 1.0 的问题,该问题与 'staticCopy 实现之间的交互有关。

检查 static 项时的健全性漏洞

在 Rust 1.41.0 中,由于 static 值内部表示的一些变化,借用检查器意外地允许了一些不健全的程序。具体来说,借用检查器不会检查 static 项是否具有正确的类型。这反过来会允许将生命周期小于 'static 的临时值赋给 static 变量

static mut MY_STATIC: &'static u8 = &0;

fn main() {
    let my_temporary = 42;
    unsafe {
        // Erroneously allowed in 1.41.0:
        MY_STATIC = &my_temporary;
    }
}

这个问题已在 1.41.1 中解决,现在程序将无法编译并报错:

error[E0597]: `my_temporary` does not live long enough
 --> src/main.rs:6:21
  |
6 |         MY_STATIC = &my_temporary;
  |         ------------^^^^^^^^^^^^^
  |         |           |
  |         |           borrowed value does not live long enough
  |         assignment requires that `my_temporary` is borrowed for `'static`
7 |     }
8 | }
  | - `my_temporary` dropped here while still borrowed

您可以在问题 #69114 中了解更多关于此 bug 的信息,以及修复该问题的 PR

Copy 实现中尊重 'static 生命周期

自 Rust 1.0 发布以来,以下错误程序一直能够编译通过:

#[derive(Clone)]
struct Foo<'a>(&'a u32);
impl Copy for Foo<'static> {}

fn main() {
    let temporary = 2;
    let foo = (Foo(&temporary),);
    drop(foo.0); // Accessing a part of `foo` is necessary.
    drop(foo.0); // Indexing an array would also work.
}

在 Rust 1.41.1 中,这个问题通过与上面修复那个问题的同一个 PR 得到了修复。现在编译该程序会产生以下错误:

error[E0597]: `temporary` does not live long enough
  --> src/main.rs:7:20
   |
7  |     let foo = (Foo(&temporary),);
   |                    ^^^^^^^^^^ borrowed value does not live long enough
8  |     drop(foo.0);
   |          ----- copying this value requires that
   |                `temporary` is borrowed for `'static`
9  |     drop(foo.0);
10 | }
   | - `temporary` dropped here while still borrowed

发生此错误是因为 Foo<'a> 在某个 'a 下,仅当 'a: 'static 时才实现 Copy trait。然而,带有生命周期 '0temporary 变量的生命周期并不比 'static 长,因此 Foo<'0> 没有实现 Copy trait,所以在第二次使用 drop 时应该是一个错误。

错误编译的边界检查导致段错误

在少数情况下,使用 Rust 1.41.0 编译的程序会省略内存分配代码中的边界检查。如果提供了越界的值,这会导致段错误。错误编译的根本原因是 LLVM 优化 pass 中的一项更改,该更改在 LLVM 9 中引入,并在 LLVM 10 中恢复。

Rust 1.41.0 使用了 LLVM 9 的一个快照,因此我们在 Rust 1.41.1 中挑选了该恢复提交,解决了错误编译问题。您可以在 问题 #69225 中了解更多关于此 bug 的信息

1.41.1 的贡献者

许多人齐心协力创建了 Rust 1.41.1。没有大家的努力,我们不可能做到这一点。感谢大家!