宣布Rust 1.59.0

119 阅读5分钟

Rust团队发布了新版本的Rust,即1.59.0。Rust是一种编程语言,它使每个人都能建立可靠和高效的软件。


今天的发布正值普京的军队突然入侵乌克兰,吸引了全世界的注意力。在讨论新的Rust版本的细节之前,我们要声明,我们与乌克兰人民站在一起,并对所有受这场冲突影响的人表示支持。


如果你已经通过rustup安装了以前的Rust版本,你可以用1.59.0获得。

rustup update stable

如果你还没有,你可以从我们网站的相应页面获得rustup,并在GitHub上查看1.59.0的详细发布说明

1.59.0稳定版中的内容

内联汇编

Rust语言现在支持内联汇编。这使得许多需要对其执行进行非常低级的控制,或者需要访问专门的机器指令的应用程序成为可能。

例如,在为x86-64目标编译时,你现在可以写。

use std::arch::asm;

// Multiply x by 6 using shifts and adds
let mut x: u64 = 4;
unsafe {
    asm!(
        "mov {tmp}, {x}",
        "shl {tmp}, 1",
        "shl {x}, 2",
        "add {x}, {tmp}",
        x = inout(reg) x,
        tmp = out(reg) _,
    );
}
assert_eq!(x, 4 * 6);

asm!global_asm!宏中用于命名寄存器的格式字符串语法与Rust格式字符串中使用的相同,所以对于Rust程序员来说,应该感到非常熟悉。

汇编语言和内联汇编可用的指令根据目标架构的不同而不同。今天,稳定的Rust编译器支持以下架构的内联汇编。

  • x86和x86-64
  • ARM
  • AArch64
  • RISC-V

你可以在Rust By Example中看到更多内联汇编的例子,并在参考文献中找到更详细的文档。

去结构化赋值

你现在可以使用元组、切片和结构模式作为赋值的左手边。

let (a, b, c, d, e);

(a, b) = (1, 2);
[c, .., d, _] = [1, 2, 3, 4, 5];
Struct { e, .. } = Struct { e: 5, f: 3 };

assert_eq!([1, 2, 1, 4, 5], [a, b, c, d, e]);

这使得赋值与let 绑定更加一致,后者长期以来一直支持同样的东西。请注意,不允许使用运算符(如+= )进行重构赋值。

构造泛型的缺省值和交织

泛型类型现在可以为它们的常量泛型指定默认值。例如,你现在可以这样写。

struct ArrayStorage<T, const N: usize = 2> {
    arr: [T; N],
}

impl<T> ArrayStorage<T> {
    fn new(a: T, b: T) -> ArrayStorage<T> {
        ArrayStorage {
            arr: [a, b],
        }
    }
}

以前,类型参数被要求放在所有常量参数之前。 这一限制已经被放宽,你现在可以将它们交织起来。

fn cartesian_product<
    T, const N: usize,
    U, const M: usize,
    V, F
>(a: [T; N], b: [U; M], f: F) -> [[V; N]; M]
where
    F: FnMut(&T, &U) -> V
{
    // ...
}

未来的不兼容警告

有时Rust编译器中的错误会导致它接受不应该被接受的代码。这方面的一个例子是在安全代码中允许借用打包的结构域

虽然这种情况很少发生,但当你的项目所使用的crate中的代码将不再被允许时,它可能是相当具有破坏性的。事实上,你可能不会注意到,直到你的项目莫名其妙地停止构建

现在,当一个依赖关系将被未来的Rust版本所拒绝时,Cargo会向你发出警告。在运行cargo buildcargo check ,你可能会看到。

warning: the following packages contain code that will be rejected by a future version of Rust: old_dep v0.1.0
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`

你可以运行警告中提到的cargo report 命令来查看将被拒绝的代码的完整报告。这让你有时间在它破坏你的构建之前升级你的依赖关系。

创建剥离的二进制文件

从你发布的二进制文件中剥离不必要的信息(如调试信息),使其更小,这通常是有用的。

虽然在创建二进制文件后一直可以手动操作,但现在 cargo 和 rustc 支持在二进制文件链接时进行剥离。要启用这个功能,请在你的Cargo.toml 中添加以下内容。

[profile.release]
strip = "debuginfo"

这将导致调试信息从发布的二进制文件中被剥离。你也可以提供"symbols" 或只提供true 来剥离所有支持的符号信息。

标准库通常带有调试符号和行级调试信息,所以在没有启用调试符号的情况下生成的Rust二进制文件仍然默认包括标准库的调试信息。使用strip选项可以删除这些额外的信息,产生更小的Rust二进制文件。

更多细节请参见Cargo的文档

默认关闭增量编译

1.59.0版本默认关闭了增量编译(除非通过环境变量明确要求:RUSTC_FORCE_INCREMENTAL=1 )。这减轻了一个已知错误的影响,#94124,它可能会在开启增量编译时导致反序列化错误(和恐慌)。

#94124的具体修复已经落地,目前在1.60测试版中,将在六周后发货。我们目前还没有意识到其他问题会促使我们决定在1.60稳定版中禁用增量编译,如果没有出现这些问题,1.60稳定版很可能会再次重新启用增量编译。在测试版和夜间版中,增量编译仍然是默认开启的。

一如既往,我们鼓励用户在夜间和测试版频道上进行测试,并报告你发现的问题:特别是对于增量错误,这是确保Rust团队能够判断是否存在故障以及影响到多少用户的最好方法。

稳定的API

以下方法和特性的实现现在已经稳定了。

以下之前稳定的函数现在是const

其他变化

在Rust 1.59.0版本中还有其他变化。请查看RustCargoClippy的变化。

1.59.0的贡献者

很多人一起创造了Rust 1.59.0,没有你们,我们不可能做到,谢谢你们!"。