|
| 1 | +# Additions to the prelude |
| 2 | + |
| 3 | +🚧 The 2024 Edition has not yet been released and hence this section is still "under construction". |
| 4 | +More information may be found in the tracking issue at <https://github.com/rust-lang/rust/issues/121042>. |
| 5 | + |
| 6 | +## Summary |
| 7 | + |
| 8 | +- The [`Future`] and [`IntoFuture`] traits are now part of the prelude. |
| 9 | +- This might make calls to trait methods ambiguous which could make some code fail to compile. |
| 10 | + |
| 11 | +[`Future`]: ../../std/future/trait.Future.html |
| 12 | +[`IntoFuture`]: ../../std/future/trait.IntoFuture.html |
| 13 | + |
| 14 | +## Details |
| 15 | + |
| 16 | +The [prelude of the standard library](../../std/prelude/index.html) is the module containing everything that is automatically imported in every module. |
| 17 | +It contains commonly used items such as `Option`, `Vec`, `drop`, and `Clone`. |
| 18 | + |
| 19 | +The Rust compiler prioritizes any manually imported items over those from the prelude, |
| 20 | +to make sure additions to the prelude will not break any existing code. |
| 21 | +For example, if you have a crate or module called `example` containing a `pub struct Option;`, |
| 22 | +then `use example::*;` will make `Option` unambiguously refer to the one from `example`; |
| 23 | +not the one from the standard library. |
| 24 | + |
| 25 | +However, adding a _trait_ to the prelude can break existing code in a subtle way. |
| 26 | +For example, a call to `x.poll()` which comes from a `MyPoller` trait might fail to compile if `std`'s `Future` is also imported, because the call to `poll` is now ambiguous and could come from either trait. |
| 27 | + |
| 28 | +As a solution, Rust 2024 will use a new prelude. |
| 29 | +It's identical to the current one, except for two new additions: |
| 30 | + |
| 31 | +- [`std::future::Future`][`Future`] |
| 32 | +- [`std::future::IntoFuture`][`IntoFuture`] |
| 33 | + |
| 34 | +## Migration |
| 35 | + |
| 36 | +🚧 The automatic migration for this has not yet been implemented. |
| 37 | + |
| 38 | +### Migration needed |
| 39 | + |
| 40 | +#### Conflicting trait methods |
| 41 | + |
| 42 | +When two traits that are in scope have the same method name, it is ambiguous which trait method should be used. For example: |
| 43 | + |
| 44 | +```rust,edition2021 |
| 45 | +trait MyPoller { |
| 46 | + // This name is the same as the `poll` method on the `Future` trait from `std`. |
| 47 | + fn poll(&self) { |
| 48 | + println!("polling"); |
| 49 | + } |
| 50 | +} |
| 51 | +
|
| 52 | +impl<T> MyPoller for T {} |
| 53 | +
|
| 54 | +fn main() { |
| 55 | + // Pin<&mut async {}> implements both `std::future::Future` and `MyPoller`. |
| 56 | + // If both traits are in scope (as would be the case in Rust 2024), |
| 57 | + // then it becomes ambiguous which `poll` method to call |
| 58 | + core::pin::pin!(async {}).poll(); |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +We can fix this by using fully qualified syntax: |
| 63 | + |
| 64 | +```rust,ignore |
| 65 | +fn main() { |
| 66 | + // Now it is clear which trait method we're referring to |
| 67 | + <_ as MyPoller>::poll(&core::pin::pin!(async {})); |
| 68 | +} |
| 69 | +``` |
0 commit comments