likes
comments
collection
share

Rust 资讯:新版本 1.78.0 发布

作者站长头像
站长
· 阅读数 80

原文链接

2024 年 5 月 2 日 · Rust 发布团队

Rust 团队很高兴地宣布 Rust 的新版本 1.78.0。Rust 是一种编程语言,它正在帮助每个人构建可靠且高效的软件。

如果你已经通过 rustup 安装了 Rust 的先前版本,你可以通过以下命令获取 1.78.0:

$ rustup update stable

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

如果你想帮助我们测试未来的版本,你可以考虑本地更新到 beta 频道(rustup default beta)或 nightly 频道(rustup default nightly)。请报告你可能遇到的任何错误!

Rust 1.78.0 稳定版中的内容

诊断属性

Rust 现在支持一个 #[diagnostic] 属性命名空间来影响编译器错误消息。这些被视为提示,编译器不一定需要使用它们,提供编译器无法识别的诊断也不会导致错误。这种灵活性允许源代码提供诊断,即使这些诊断不被所有编译器支持,无论这些编译器是不同版本还是完全不同的实现。

随着这个命名空间,支持的第一个属性是 #[diagnostic::on_unimplemented],它可以放在一个 trait 上,以自定义当该 trait 被要求但未在类型上实现时的消息。考虑在稳定请求中给出的示例:

#[diagnostic::on_unimplemented(
    message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`",
    label = "My Label",
    note = "Note 1",
    note = "Note 2"
)]
trait ImportantTrait<A> {}

fn use_my_trait(_: impl ImportantTrait<i32>) {}

fn main() {
    use_my_trait(String::new());
}

之前,编译器会给出如下内置错误:

error[E0277]: the trait bound `String: ImportantTrait<i32>` is not satisfied
  --> src/main.rs:12:18
   |
12 |     use_my_trait(String::new());
   |     ------------ ^^^^^^^^^^^^^ the trait `ImportantTrait<i32>` is not implemented for `String`
   |     |
   |     required by a bound introduced by this call
   |

有了 #[diagnostic::on_unimplemented],其自定义消息填充主要错误行,自定义标签被放在源输出上。原始标签仍作为帮助输出,并且任何自定义说明也会写出。(这些确切的细节可能会有所改变。)

error[E0277]: My Message for `ImportantTrait<i32>` is not implemented for `String`
  --> src/main.rs:12:18
   |
12 |     use_my_trait(String::new());
   |     ------------ ^^^^^^^^^^^^^ My Label
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `ImportantTrait<i32>` is not implemented for `String`
   = note: Note 1
   = note: Note 2

对于 trait 作者,如果你能提供比仅仅讨论缺少的实现更好的提示,这种诊断会更有用。例如,这是标准库中的一个简化示例:

#[diagnostic::on_unimplemented(
    message = "the size for values of type `{Self}` cannot be known at compilation time",
    label = "doesn't have a size known at compile-time"
)]
pub trait Sized {}

有关更多信息,请参阅诊断工具属性命名空间的参考部分。

断言不安全前提条件

Rust 标准库对不安全函数的前提条件有许多断言,但历史上这些断言只在 #[cfg(debug_assertions)] 构建的标准库中启用,以避免影响发布性能。然而,由于标准库通常以发布模式编译和分发,大多数 Rust 开发者几乎不会执行这些检查。

现在,这些断言的条件被推迟到代码生成,因此它们会根据用户自己的调试断言设置进行检查——默认情况下在调试和测试构建中启用。这个更改有助于用户捕捉代码中的未定义行为,尽管具体检查的细节通常不是稳定的。

例如,slice::from_raw_parts 需要一个对齐的非空指针。以下使用故意未对齐的指针的例子有未定义行为,虽然如果你运气不好,过去它可能看起来“工作正常”,但现在调试断言可以捕捉到它:

fn main() {
    let slice: &[u8] = &[1, 2, 3, 4, 5];
    let ptr = slice.as_ptr();

    // 创建一个偏移量,使得 `ptr` 总是与 `u16` 的正确对齐错位
    let i = usize::from(ptr as usize & 1 == 0);
    
    let slice16: &[u16] = unsafe { std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 2) };
    dbg!(slice16);
}
thread 'main' panicked at library/core/src/panicking.rs:220:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.

确定性的重新对齐

标准库有一些更改指针和切片对齐的函数,但它们之前有一些使其难以在实践中依赖的警告,如果你严格按照它们的文档。这些警告主要是为了防范常量评估,但它们只对非常量使用是稳定的。现在它们承诺根据实际输入具有一致的运行时行为。

pointer::align_offset 计算更改指针到给定对齐所需的偏移量。如果不可能,它返回 usize::MAX,但之前它被允许总是返回 usize::MAX,现在这种行为被移除。

slice::align_toslice::align_to_mut 都会将切片转换为对齐的中间切片和剩余的未对齐的头尾切片。这些方法现在承诺返回最大的中间部分,而不是允许实现返回不太优化的结果,如将所有内容返回为头切片。

稳定的 API

  • impl Read for &Stdin
  • 接受多个 std::error::Error 相关实现的非 'static 生命周期
  • 使 impl<Fd: AsFd> impl 接受 ?Sized
  • impl From<TryReserveError> for io::Error

这些 API 现在在常量上下文中是稳定的:

  • Barrier::new()

兼容性说明

如之前宣布的那样,Rust 1.78 将其最低要求提高到 Windows 10,适用于以下目标:

  • x86_64-pc-windows-msvc
  • i686-pc-windows-msvc
  • x86_64-pc-windows-gnu
  • i686-pc-windows-gnu
  • x86_64-pc-windows-gnullvm
  • i686-pc-windows-gnullvm

Rust 1.78 已将其捆绑的 LLVM 升级到版本 18,完成了之前宣布的 x86-32 和 x86-64 目标的 u128/i128 ABI 更改。使用其自身 LLVM 版本低于 18 的分发者仍可能面临该帖子中提到的调用约定错误。

其他更改

查看 Rust、Cargo 和 Clippy 中更改的所有内容。

1.78.0 的贡献者

许多人共同努力创造了 Rust 1.78.0。没有你们的帮助,我们无法完成这一切。感谢大家!

变化总结

Rust 1.78.0 引入了新的诊断属性命名空间,使开发者能够更好地定制编译器错误消息。此外,标准库的断言机制也得到了改进,现在会在用户自己的调试设置下进行检查,帮助捕捉未定义行为。

转载自:https://juejin.cn/post/7370925894662242356
评论
请登录