diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6d03c91..e5a56e3 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -127,7 +127,7 @@ - [`gen` keyword](rust-2024/gen-keyword.md) - [Reserved syntax](rust-2024/reserved-syntax.md) - [標準ライブラリ](rust-2024/standard-library.md) - - [Changes to the prelude](rust-2024/prelude.md) + - [Prelude への変更点](rust-2024/prelude.md) - [Add `IntoIterator` for `Box<[T]>`](rust-2024/intoiterator-box-slice.md) - [Newly unsafe functions](rust-2024/newly-unsafe-functions.md) - [Cargo](rust-2024/cargo.md) diff --git a/src/rust-2024/prelude.md b/src/rust-2024/prelude.md index bbad82c..f97e36c 100644 --- a/src/rust-2024/prelude.md +++ b/src/rust-2024/prelude.md @@ -1,42 +1,95 @@ -> **Rust Edition Guide は現在 Rust 2024 のアップデート作業に向けて翻訳作業中です。本ページはある時点での英語版をコピーしていますが、一部のリンクが動作しない場合や、最新情報が更新されていない場合があります。問題が発生した場合は、[原文(英語版)](https://doc.rust-lang.org/nightly/edition-guide/introduction.html)をご参照ください。** - + + +# Prelude への変更点 + + +## 概要 + +- [`Future`] と [`IntoFuture`] トレイトがプレリュードに追加されました。 +- その結果、一部のコードでトレイトメソッドの呼び出しが一意に決定できなくなり、コンパイルに失敗する可能性があります。 + + + +[`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html +[`IntoFuture`]: https://doc.rust-lang.org/std/future/trait.IntoFuture.html + + +## 詳細 + +[標準ライブラリのプレリュード](https://doc.rust-lang.org/std/prelude/index.html)は、すべてのモジュールで自動的にインポートされるアイテムをまとめたモジュールです。例えば、`Option`、`Vec`、`drop`、`Clone` など、よく使われるアイテムが含まれます。 + + + + +Rust コンパイラは、プレリュードからインポートされるアイテムよりも、明示的にインポートされたアイテムを優先します。これにより、プレリュードに追加があっても既存のコードは壊れないようになっています。たとえば、`example` というクレートやモジュールに `pub struct Option;` が定義されている場合、`use example::*;` とした場合、`Option` は標準ライブラリのものではなく、必ず `example` のものが使われます。 + +ただし、*トレイト*をプレリュードに追加すると、既存のコードに微妙な影響が生じて壊れることがあります。たとえば、`MyPoller` というトレイトの `poll` メソッドを `x.poll()` と呼び出しているコードに、`std`(標準ライブラリ)の `Future` トレイトも同時にインポートされている場合、どちらの `poll` を呼ぶべきかが一意に決定できなくなり、コンパイルに失敗する可能性があります。 + + + +そのため、Rust 2024 では新しいプレリュードが導入されます。基本的な内容は現行のものと変わりませんが、以下の項目が追加されています: + +- 追加された項目: - [`std::future::Future`][`Future`] - [`std::future::IntoFuture`][`IntoFuture`] + +## 移行 + + + +### 競合するトレイトメソッド + + +スコープ内にある二つのトレイトが同じメソッド名を持つ場合、どちらのトレイトメソッドを使うべきかが一意に決定できなくなってしまいます。例えば、次のコードをご覧ください。 + + +```rust,edition2021 +trait MyPoller { + // この名前は、`std` の `Future` トレイトにある `poll` メソッドと同じです。 + fn poll(&self) { + println!("polling"); + } +} + +impl MyPoller for T {} + +fn main() { + // `Pin<&mut async {}>` は `std::future::Future` と `MyPoller` の両方を実装しています。 + // 両方のトレイトがスコープ内にある場合(Rust 2024 ではこれが発生する)、 + // どの `poll` メソッドを呼び出すかが曖昧になります。 + core::pin::pin!(async {}).poll(); +} +``` + + +完全修飾構文を使うと、すべてのエディションで正しく動作するようになります。 + +```rust,ignore +fn main() { + // これで、どのトレイトのメソッドを参照しているのかが明確になりました。 + <_ as MyPoller>::poll(&core::pin::pin!(async {})); +} +``` + + + +また、[`rust_2024_prelude_collisions`] リントは、一意に決定できない曖昧なメソッド呼び出しを自動的に完全修飾構文に変更してくれます。このリントは `rust-2024-compatibility` リントグループの一部であり、`cargo fix --edition` を実行すると自動的に適用されます。Rust 2024 エディションに互換性のあるコードに移行するには、次のコマンドを実行してください。 ```sh cargo fix --edition ``` + + +もしくは、完全修飾が必要な箇所を見つけるために、リントを手動で有効にすることもできます。 + +```rust +// 手動で移行を行うには、クレートのルートにこれを追加してください。 +#![warn(rust_2024_prelude_collisions)] +``` + + + +[`rust_2024_prelude_collisions`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#rust-2024-prelude-collisions \ No newline at end of file