前奏的更改

概要

  • FutureIntoFuture 特性现在是序幕的一部分。
  • 这可能会使对特性方法的调用变得模棱两可,这可能导致某些代码编译失败。
  • RustcEncodableRustcDecodable 已从序幕中移除。

详情

标准库的序幕 是一个模块,其中包含每个模块中自动导入的所有内容。它包含常用的项,例如 OptionVecdropClone

Rust 编译器优先考虑任何手动导入的项,而不是来自序幕的项,以确保添加到序幕的内容不会破坏任何现有代码。例如,如果您有一个名为 example 的 crate 或模块,其中包含 pub struct Option;,那么 use example::*; 将使 Option 明确地指向来自 example 的那个;而不是来自标准库的那个。

然而,向序幕添加*特性*可能会以一种微妙的方式破坏现有代码。例如,如果也导入了 stdFuture,则来自 MyPoller 特性的 x.poll() 调用可能会编译失败,因为现在对 poll 的调用是模棱两可的,并且可能来自任一特性。

作为解决方案,Rust 2024 将使用一个新的序幕。它与当前的序幕相同,除了以下更改

RustcEncodableRustcDecodable 移除

RustcEncodableRustcDecodable 是两个未文档化的 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)]
}

RustcEncodableRustcDecodable

强烈建议您迁移到不同的序列化库(如果您仍在使用这些)。但是,这些 derive 宏仍然在标准库中可用,只是现在需要从较旧的序幕中导入它们。

#![allow(unused)]
fn main() {
#[allow(soft_unstable)]
use core::prelude::v1::{RustcDecodable, RustcEncodable};
}

此更改没有自动迁移;您需要手动进行更新。