发布 Rust 1.63.0

2022 年 8 月 11 日 · Rust 发布团队

Rust 团队很高兴地宣布 Rust 新版本 1.63.0 发布。Rust 是一门赋予每个人构建可靠且高效软件能力的编程语言。

如果你之前已经通过 rustup 安装了 Rust,可以通过以下命令更新到 1.63.0:

$ rustup update stable

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

如果你想通过测试未来版本来帮助我们,可以考虑在本地更新到使用 beta 通道 (rustup default beta) 或 nightly 通道 (rustup default nightly)。如果你遇到任何 bug,请报告

1.63.0 stable 版本有什么新内容

作用域线程 (Scoped threads)

自 1.0 版本以来,Rust 代码就可以使用 std::thread::spawn 启动新线程,但这个函数将其闭包绑定到 'static 生命周期。这大致意味着线程当前必须拥有传递到其闭包中的任何参数的所有权;你不能将借用的数据传递给线程。在线程预计会在函数结束时退出(通过 join())的情况下,这并非严格必要,并且可能需要像将数据放入 Arc 这样的变通方法。

现在,随着 1.63.0 的发布,标准库增加了*作用域*线程 (scoped threads),这允许生成一个借用自局部栈帧的线程。std::thread::scope API 提供了必要的保证,即在自身返回之前,所有生成的线程都将已经退出,从而可以安全地借用数据。下面是一个示例

let mut a = vec![1, 2, 3];
let mut x = 0;

std::thread::scope(|s| {
    s.spawn(|| {
        println!("hello from the first scoped thread");
        // We can borrow `a` here.
        dbg!(&a);
    });
    s.spawn(|| {
        println!("hello from the second scoped thread");
        // We can even mutably borrow `x` here,
        // because no other threads are using it.
        x += a[0] + a[2];
    });
    println!("hello from the main thread");
});

// After the scope, we can modify and access our variables again:
a.push(4);
assert_eq!(x, a.len());

原始文件描述符/句柄的 Rust 所有权 (I/O 安全)

以前,处理接受原始文件描述符(在 Unix 风格平台上)或句柄(在 Windows 上)的平台 API 的 Rust 代码通常直接使用描述符的平台特定表示(例如,c_int 或别名 RawFd)。对于此类原生 API 的 Rust 绑定,类型系统当时未能编码 API 是会获得文件描述符的所有权(例如 close)还是仅仅借用它(例如 dup)。

现在,Rust 提供了诸如 BorrowedFdOwnedFd 这样的包装类型,它们被标记为 #[repr(transparent)],这意味着 extern "C" 绑定可以直接使用这些类型来编码所有权语义。请参阅已稳定 API 部分以获取 1.63 中稳定的完整包装类型列表,目前,它们在 cfg(unix) 平台、Windows 和 WASI 上可用。

我们建议新的 API 使用这些类型,而不是之前的类型别名(如 RawFd)。

const Mutex、RwLock、Condvar 初始化

Condvar::newMutex::newRwLock::new 函数现在可以在 const 上下文中调用,这使得创建带有 MutexRwLockCondvar 值的全局静态时,可以避免使用像 lazy_static 这样的 crate。这基于 1.62 中的工作,以在 Linux 上启用更精简、更快的 mutex。

对于带有 impl Trait 的函数中的泛型使用 Turbofish

对于像 fn foo<T>(value: T, f: impl Copy) 这样的函数签名,之前通过 turbofish 指定 T 的具体类型是错误的:foo::<u32>(3, 3) 会失败并报以下错误:

error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
 --> src/lib.rs:4:11
  |
4 |     foo::<u32>(3, 3);
  |           ^^^ explicit generic argument not allowed
  |
  = note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information

在 1.63 中,此限制放宽了,可以指定泛型的显式类型。然而,尽管 impl Trait 参数解糖为泛型,但它仍然是不透明的,不能通过 turbofish 指定。

非词法生命周期 (Non-lexical lifetimes) 迁移完成

正如这篇博文详细介绍的,我们已经从所有版本的 rustc 中完全移除了之前的词法借用检查器,完全启用了新的非词法版本的借用检查器。由于借用检查器不影响 rustc 的输出,这不会改变任何程序的行为,但它完成了一个长期进行的迁移(始于 2018 版本 NLL 的初步稳定化),以便在 Rust 的所有版本中提供新借用检查器的全部优势。对于大多数用户来说,此更改将为某些借用检查错误带来稍微更好的诊断信息,但不会影响他们可以编写的代码。

您可以在2018 版本发布公告的这一部分阅读有关非词法生命周期的更多信息。

稳定化的 API

以下方法和 trait 实现现已稳定:

以下 API 现在可在 const 上下文中使用:

其他变更

Rust 1.63.0 版本中还有其他变更。请查看 RustCargoClippy 中的变更内容。

1.63.0 贡献者

许多人共同努力促成了 Rust 1.63.0 的发布。没有你们,我们不可能做到这一切。感谢你们!