前奏的更改
概要
Future
和IntoFuture
特性现在是序幕的一部分。- 这可能会使对特性方法的调用变得模棱两可,这可能导致某些代码编译失败。
RustcEncodable
和RustcDecodable
已从序幕中移除。
详情
标准库的序幕
是一个模块,其中包含每个模块中自动导入的所有内容。它包含常用的项,例如 Option
、Vec
、drop
和 Clone
。
Rust 编译器优先考虑任何手动导入的项,而不是来自序幕的项,以确保添加到序幕的内容不会破坏任何现有代码。例如,如果您有一个名为 example
的 crate 或模块,其中包含 pub struct Option;
,那么 use example::*;
将使 Option
明确地指向来自 example
的那个;而不是来自标准库的那个。
然而,向序幕添加*特性*可能会以一种微妙的方式破坏现有代码。例如,如果也导入了 std
的 Future
,则来自 MyPoller
特性的 x.poll()
调用可能会编译失败,因为现在对 poll
的调用是模棱两可的,并且可能来自任一特性。
作为解决方案,Rust 2024 将使用一个新的序幕。它与当前的序幕相同,除了以下更改
- 添加
- 移除
RustcEncodable
RustcDecodable
RustcEncodable
和 RustcDecodable
移除
RustcEncodable
和 RustcDecodable
是两个未文档化的 derive 宏,它们已从序幕中移除。这些在 Rust 1.0 之前已被弃用,但仍保留在标准库序幕中。2024 版本已从序幕中移除它们,因为预计不会使用它们。
如果万一有项目仍在使用这些,建议切换到序列化库,例如在 crates.io
上找到的那些。
迁移
冲突的特性方法
当作用域内的两个特性具有相同的方法名称时,不清楚应该使用哪个特性方法。例如
trait MyPoller { // This name is the same as the `poll` method on the `Future` trait from `std`. fn poll(&self) { println!("polling"); } } impl<T> MyPoller for T {} fn main() { // Pin<&mut async {}> implements both `std::future::Future` and `MyPoller`. // If both traits are in scope (as would be the case in Rust 2024), // then it becomes ambiguous which `poll` method to call core::pin::pin!(async {}).poll(); }
我们可以通过使用完全限定的语法来修复此问题,使其在所有版本上都有效。
fn main() {
// Now it is clear which trait method we're referring to
<_ as MyPoller>::poll(&core::pin::pin!(async {}));
}
rust_2024_prelude_collisions
lint 将自动修改任何模棱两可的方法调用以使用完全限定的语法。此 lint 是 rust-2024-compatibility
lint 组的一部分,该组将在运行 cargo fix --edition
时自动应用。要迁移您的代码以与 Rust 2024 版本兼容,请运行
cargo fix --edition
或者,您可以手动启用 lint 以查找需要添加这些限定的位置。
#![allow(unused)] fn main() { // Add this to the root of your crate to do a manual migration. #![warn(rust_2024_prelude_collisions)] }
RustcEncodable
和 RustcDecodable
强烈建议您迁移到不同的序列化库(如果您仍在使用这些)。但是,这些 derive 宏仍然在标准库中可用,只是现在需要从较旧的序幕中导入它们。
#![allow(unused)] fn main() { #[allow(soft_unstable)] use core::prelude::v1::{RustcDecodable, RustcEncodable}; }
此更改没有自动迁移;您需要手动进行更新。