diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6d03c91..5d2ed41 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -129,7 +129,7 @@ - [標準ライブラリ](rust-2024/standard-library.md) - [Changes to the 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) + - [新しい unsafe 関数](rust-2024/newly-unsafe-functions.md) - [Cargo](rust-2024/cargo.md) - [Cargo: Rust-version aware resolver](rust-2024/cargo-resolver.md) - [Cargo: Table and key name consistency](rust-2024/cargo-table-key-names.md) diff --git a/src/rust-2024/newly-unsafe-functions.md b/src/rust-2024/newly-unsafe-functions.md index a9e02fc..d208799 100644 --- a/src/rust-2024/newly-unsafe-functions.md +++ b/src/rust-2024/newly-unsafe-functions.md @@ -1,55 +1,141 @@ -> **Rust Edition Guide は現在 Rust 2024 のアップデート作業に向けて翻訳作業中です。本ページはある時点での英語版をコピーしていますが、一部のリンクが動作しない場合や、最新情報が更新されていない場合があります。問題が発生した場合は、[原文(英語版)](https://doc.rust-lang.org/nightly/edition-guide/introduction.html)をご参照ください。** - + + +# unsafe 関数 + + +## 概要 + +- 以下の関数が新たに [`unsafe`] としてマークされました: + - [`std::env::set_var`] + - [`std::env::remove_var`] + - [`std::os::unix::process::CommandExt::before_exec`] + + + +[`unsafe`]: https://doc.rust-lang.org/reference/unsafe-keyword.html#unsafe-functions-unsafe-fn +[`std::env::set_var`]: https://doc.rust-lang.org/std/env/fn.set_var.html +[`std::env::remove_var`]: https://doc.rust-lang.org/std/env/fn.remove_var.html +[`std::os::unix::process::CommandExt::before_exec`]: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#method.before_exec + + +## 詳細 + +標準ライブラリのいくつかの関数は、本来 `unsafe` であるべきであることが時間とともに明らかになってきました。しかし、関数を unsafe に変更すると、既存のコードでは `unsafe` ブロックで囲む必要が生じるため、破壊的変更となる可能性があります。この破壊的変更を避けるため、これらの関数は 2024 Edition から `unsafe` にマークされますが、以前のエディションでは `unsafe` を要求しません。 + + +### `std::env::{set_var, remove_var}` + + + +[`std::env::set_var`] や [`std::env::remove_var`] をマルチスレッド環境で呼び出すことは、一部のプラットフォームにおけるプロセス環境の管理方法の制約により、安全でない可能性があります。標準ライブラリではこれらの関数をもともと安全な関数として定義していましたが、それが適切でなかったことが後に判明しました。 + + +これらの関数を呼び出す際は、他のスレッドが動作していないことを保証する必要があります。詳細は、各関数の [Safety] セクションを参照してください。 + + +[Safety]: https://doc.rust-lang.org/std/env/fn.set_var.html#safety + + ### `std::os::unix::process::CommandExt::before_exec` + + +[`std::os::unix::process::CommandExt::before_exec`] は、Unix 固有の関数であり、`exec` を呼び出す前にクロージャを実行するための手段を提供します。この関数は Rust 1.37 で非推奨となり、代わりに [`pre_exec`] が導入されました。`pre_exec` は同じ機能を提供しますが、明示的に `unsafe` としてマークされました。 + + +`before_exec` はすでに非推奨ですが、2024 Edition から `unsafe` として正しくマークされるようになりました。これにより、まだ `pre_exec` に移行していない レガシーコードに対しても `unsafe` ブロックが必要となります。 + +なお、`before_exec` のクロージャには非常に厳格な安全性の要件があります。詳細は [Safety セクション][pre-exec-safety]を参照してください。 + + + +[`pre_exec`]: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.pre_exec +[pre-exec-safety]: https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#notes-and-safety + +## 移行 + + + +2021 Edition と 2024 Edition の両方でコードをコンパイル可能にするには、これらの関数を `unsafe` ブロック内でのみ呼び出すようにする必要があります。 + + +**⚠ 注意:** これらの関数を使用している箇所を手動で確認し、必要に応じてコードを関数が前提とする条件を満たすよう書き換えることが重要です。特に、`set_var` や `remove_var` は複数のスレッドが動作している可能性がある場合には呼び出すべきではありません。ユースケースを管理するために、環境変数とは異なる仕組みを使用する必要があるかもしれません。 + + +[`deprecated_safe_2024`] リントは両方のエディションでコンパイルできるように、これらの関数の呼び出しを自動的に `unsafe` ブロックで囲むよう修正します。これは `rust-2024-compatibility` リントグループに含まれており、`cargo fix --edition` コマンドを実行することで適用できます。Rust 2024 エディションに対応するようコードを移行するには、次のコマンドを実行します: + ```sh cargo fix --edition ``` + + +たとえば、以下のコードは: ```rust fn main() { @@ -57,22 +143,55 @@ fn main() { } ``` + +自動修正により次のように変更されます: + + + +```rust +fn main() { + // TODO: 環境変数の操作がシングルスレッドのコード内でのみ行われていることを確認する。 + unsafe { std::env::set_var("FOO", "123") }; +} +``` + + +ただし、この自動移行では、これらの関数が正しく使用されているかどうかを検証することはできません。よって、最終的な責任は開発者にあり手動でコードを確認する必要があります。 + + + +または、リントを手動で有効にして、これらの関数が呼び出されている箇所を特定することもできます。 + +```rust +// 手動で移行を行うには、クレートのルートに以下を追加してください。 +#![warn(deprecated_safe_2024)] +``` + + + +[`deprecated_safe_2024`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#deprecated-safe-2024 \ No newline at end of file diff --git a/src/rust-2024/unsafe-attributes.md b/src/rust-2024/unsafe-attributes.md index c4a2f13..7ea3073 100644 --- a/src/rust-2024/unsafe-attributes.md +++ b/src/rust-2024/unsafe-attributes.md @@ -9,9 +9,9 @@ - [`link_section`] - [`no_mangle`] -[`export_name`]: ../../reference/abi.html#the-export_name-attribute -[`link_section`]: ../../reference/abi.html#the-link_section-attribute -[`no_mangle`]: ../../reference/abi.html#the-no_mangle-attribute +[`export_name`]: https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute +[`link_section`]: https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute +[`no_mangle`]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute ## Details @@ -56,8 +56,8 @@ fn arduino_loop() { } ``` -[symbol mangling]: ../../rustc/symbol-mangling/index.html -[`unsafe_attr_outside_unsafe`]: ../../rustc/lints/listing/allowed-by-default.html#unsafe-attr-outside-unsafe +[symbol mangling]: https://doc.rust-lang.org/rustc/symbol-mangling/index.html +[`unsafe_attr_outside_unsafe`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#unsafe-attr-outside-unsafe ## Migration