Rust 1.37.0 发布公告

2019年8月15日 · Rust 发布团队

Rust 团队很高兴地宣布 Rust 的新版本 1.37.0 发布。Rust 是一种旨在赋能所有人构建可靠且高效软件的编程语言。

如果您之前通过 rustup 安装了 Rust,那么升级到 Rust 1.37.0 非常简单,只需运行:

$ rustup update stable

如果您尚未安装,您可以从我们网站的相应页面获取 rustup,并查看 GitHub 上1.37.0 的详细发布说明

1.37.0 稳定版的新特性

Rust 1.37.0 的亮点包括通过 type 别名引用 enum 变体、内置 cargo vendor、未命名的 const 项、配置引导优化、Cargo 中的 default-run 键以及 enum 上的 #[repr(align(N))]。请继续阅读以了解一些亮点,或查看详细的发布说明以获取更多信息。

通过 type 别名引用 enum 变体

在 Rust 1.37.0 中,您现在可以通过类型别名引用 enum 变体。例如:

type ByteOption = Option<u8>;

fn increment_or_zero(x: ByteOption) -> u8 {
    match x {
        ByteOption::Some(y) => y + 1,
        ByteOption::None => 0,
    }
}

在实现中,Self 的作用类似于类型别名。因此,在 Rust 1.37.0 中,您也可以使用 Self::Variant 引用 enum 变体:

impl Coin {
    fn value_in_cents(&self) -> u8 {
        match self {
            Self::Penny => 1,
            Self::Nickel => 5,
            Self::Dime => 10,
            Self::Quarter => 25,
        }
    }
}

更准确地说,Rust 现在允许您通过“类型相关的解析”,即 <MyType<..>>::Variant 来引用 enum 变体。更多详细信息请参阅稳定化报告

内置 Cargo 对 vendor 依赖的支持

在作为单独的 crate 可用多年之后,cargo vendor 命令现在直接集成到 Cargo 中。该命令获取您项目的所有依赖项,将其解压缩到 vendor/ 目录中,并显示构建期间使用 vendor 代码所需的配置片段。

在多种情况下,cargo vendor 已在生产环境中使用:Rust 编译器 rustc 使用它来在发布 tarball 中发布其所有依赖项,而使用 monorepo 的项目使用它来提交源代码控制中的依赖项代码。

为宏使用未命名的 const

您现在可以创建未命名的 const。无需为常量指定显式名称,只需将其命名为 _ 即可。例如,在 rustc 编译器中,我们发现:

/// Type size assertion where the first parameter
/// is a type and the second is the expected size.
#[macro_export]
macro_rules! static_assert_size {
    ($ty:ty, $size:expr) => {
        const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
        //    ^ Note the underscore here.
    }
}

static_assert_size!(Option<Box<String>>, 8); // 1.
static_assert_size!(usize, 8); // 2.

请注意第二个 static_assert_size!(..):由于使用了未命名的常量,您可以定义新项而不会发生命名冲突。以前您需要编写 static_assert_size!(MY_DUMMY_IDENTIFIER, usize, 8);。相反,在 Rust 1.37.0 中,现在可以更轻松地为静态分析目的创建符合人体工程学且可重用的声明式和过程式宏。

配置引导优化

rustc 编译器现在通过 -C profile-generate-C profile-use 标志支持配置引导优化 (PGO)

配置引导优化允许编译器根据实际工作负载的反馈来优化代码。它通过分两步编译程序来进行优化:

  1. 首先,程序在编译器插入的 instrumentation 的情况下构建。这通过将 -C profile-generate 标志传递给 rustc 来完成。然后,instrumentation 程序需要在示例数据上运行,并将 profiling 数据写入文件。
  2. 然后,再次构建程序,这次通过使用 -C profile-use 标志将收集的 profiling 数据反馈到 rustc 中。此构建将利用收集的数据,使编译器能够对代码放置、内联和其他优化做出更好的决策。

有关配置引导优化的更深入信息,请参阅 rustc book 中相应的章节

在 Cargo 项目中选择默认二进制文件

cargo run 非常适合快速测试 CLI 应用程序。当同一个包中存在多个二进制文件时,您必须使用 --bin 标志显式声明要运行的二进制文件的名称。这使得 cargo run 不如我们期望的那么符合人体工程学,尤其是在某个二进制文件比其他二进制文件更常被调用的情况下。

Rust 1.37.0 通过在 Cargo.toml 中添加一个新的键 default-run 来解决此问题。当在 [package] 部分声明该键时,如果未传递 --bin 标志,则 cargo run 将默认运行选择的二进制文件。

enum 上的 #[repr(align(N))]

#[repr(align(N))] 属性可用于提高类型定义的对齐方式。以前,该属性仅允许用于 structunion。在 Rust 1.37.0 中,该属性现在也可以enum 定义上使用。例如,以下类型 Align16 将按预期报告 16 作为对齐方式,而没有 #[repr(align(16))] 的自然对齐方式将为 4

#[repr(align(16))]
enum Align16 {
    Foo { foo: u32 },
    Bar { bar: u32 },
}

enum 上使用 #[repr(align(N)) 的语义与定义一个带有该对齐方式的包装 struct AlignN<T>,然后使用 AlignN<MyEnum> 相同。

#[repr(align(N))]
struct AlignN<T>(T);

库变更

在 Rust 1.37.0 中,标准库进行了一些稳定化:

其他变更

Rust 1.37 版本还有其他更改:请查看 RustCargoClippy 中的更改。

1.37.0 的贡献者

许多人共同创建了 Rust 1.37.0。没有你们所有人,我们不可能做到。谢谢!

Rust 基础设施的新赞助商

我们要感谢 Rust 基础设施的两位新赞助商,他们为 Rust 1.37.0 的实现提供了所需的资源:Amazon Web Services (AWS) 和 Microsoft Azure。

  • AWS 为发布工件(编译器、库、工具和源代码)提供了托管,通过 CloudFront 向用户提供这些工件,通过 EC2 上的 Crater 防止回归,并管理托管在 AWS 上的其他 Rust 相关基础设施。
  • Microsoft Azure 赞助了 Rust CI 基础设施的构建器,特别是资源极其密集的 rust-lang/rust 存储库。