Rust 1.41.1 发布公告

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

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

如果您之前通过 rustup 安装了 Rust,获取 Rust 1.41.1 就像

$ rustup update stable

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

1.41.1 稳定版中的内容

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

检查 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修复它的 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。但是,temporary 变量(具有某些生命周期 '0)不会超过 'static,因此 Foo<'0> 不是 Copy,因此在第二次使用 drop 时应该是一个错误。

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

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

Rust 1.41.0 使用 LLVM 9 的快照,因此我们将恢复 cherry-pick 到 Rust 1.41.1 中,解决了错误编译。 您可以在问题 #69225 中了解更多关于此错误的信息

1.41.1 的贡献者

许多人共同创建了 Rust 1.41.1。没有你们,我们无法做到。 谢谢!