From 897575addd234222ed610f99a455fb1f46c32fbf Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Wed, 19 Feb 2025 11:17:03 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=E3=80=8C=E3=82=A2=E3=83=B3=E3=82=BB?= =?UTF-8?q?=E3=83=BC=E3=83=95=E3=81=AA=20`extern`=20=E3=83=96=E3=83=AD?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=80=8D=E3=82=92=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SUMMARY.md | 2 +- src/rust-2024/unsafe-extern.md | 146 +++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/rust-2024/unsafe-extern.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ab10822..735a4fa 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -118,7 +118,7 @@ - [`if let` temporary scope](rust-2024/temporary-if-let-scope.md) - [Tail expression temporary scope](rust-2024/temporary-tail-expr-scope.md) - [Match ergonomics reservations](rust-2024/match-ergonomics.md) - - [Unsafe `extern` blocks](rust-2024/unsafe-extern.md) + - [アンセーフな `extern` ブロック](rust-2024/unsafe-extern.md) - [Unsafe attributes](rust-2024/unsafe-attributes.md) - [`unsafe_op_in_unsafe_fn` warning](rust-2024/unsafe-op-in-unsafe-fn.md) - [Disallow references to `static mut`](rust-2024/static-mut-references.md) diff --git a/src/rust-2024/unsafe-extern.md b/src/rust-2024/unsafe-extern.md new file mode 100644 index 0000000..2c66e6f --- /dev/null +++ b/src/rust-2024/unsafe-extern.md @@ -0,0 +1,146 @@ + + +# アンセーフな `extern` ブロック + + + +## 概要 + + + +- [`extern` ブロック]は `unsafe` として宣言される必要があります。 + + + +[`extern` blocks]: https://doc.rust-lang.org/reference/items/external-blocks.html + + + +## 詳細 + + + +Rust 1.82 から、[`extern` ブロック]を `unsafe` キーワードとともに宣言できるようになりました。[^RFC3484] +`unsafe` と書くことで、シグネチャが正しいことを保証するのが `extern` ブロックを書いた人の責任であることが明確になります。 +シグネチャが正しくないと、未定義動作になってしまいます。 + + + +以下に、アンセーフな `extern` ブロック構文の例を示します。 + + + +```rust +unsafe extern "C" { + // (libm の) sqrt 関数は任意の `f64` 引数を取れる + pub safe fn sqrt(x: f64) -> f64; + + // (libc の) strlen 関数は有効なポインタを要求するため、 + // アンセーフな関数として宣言する + pub unsafe fn strlen(p: *const std::ffi::c_char) -> usize; + + // safe も unsafe もない関数はデフォルトではアンセーフとなる + pub fn free(p: *mut core::ffi::c_void); + + pub safe static IMPORTANT_BYTES: [u8; 256]; +} +``` + + + +`extern` ブロックを `unsafe` とできるのに加え、`extern` ブロック内の個々のアイテムを `safe` か `unsafe` と明示できるようになりました。 +`safe` のついたアイテムは、`unsafe` ブロックなしに使用できます。 + + + +2024 エディション以降、`extern` ブロックには必ず `unsafe` を付与する必要があります。 +これは、extern 定義が遵守すべき安全性基準が存在するということを明確にするためです。 + + + +[^RFC3484]: 元の提案については [RFC 3484](https://github.com/rust-lang/rfcs/blob/master/text/3484-unsafe-extern-blocks.md) 参照のこと。 + + + +## 移行 + + + +[`missing_unsafe_on_extern`] リントで `extern` ブロックに `unsafe` を自動付与できます。 +このリントは、自動エディション移行に含まれる `rust-2024-compatibility` リントグループの一部です。 +コードを Rust 2024 互換に移行するには、以下を実行します。 + +```sh +cargo fix --edition +``` + + + +ただし、自動移行ツールは `extern` ブロックのシグネチャが正しいことを検証するわけではありません。 +それを保証するのは、変わらずプログラマの責任です。 + + + +変更の必要のある `unsafe` ブロックを検出するリントを手動で有効化することもできます。 + + + +```rust +// クレートのトップレベルに以下を追加すると手動移行できる +#![warn(missing_unsafe_on_extern)] +``` + + + +[`missing_unsafe_on_extern`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#missing-unsafe-on-extern From 9bd2281638b151881e92284503a4f53d540ab23f Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Wed, 19 Feb 2025 12:04:45 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E3=80=8C=E3=82=A2=E3=83=B3=E3=82=BB?= =?UTF-8?q?=E3=83=BC=E3=83=95=E3=81=AA=E3=82=A2=E3=83=88=E3=83=AA=E3=83=93?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=83=88=E3=80=8D=E3=82=92=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SUMMARY.md | 2 +- src/rust-2024/unsafe-attributes.md | 183 +++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/rust-2024/unsafe-attributes.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ab10822..67fb8b0 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -119,7 +119,7 @@ - [Tail expression temporary scope](rust-2024/temporary-tail-expr-scope.md) - [Match ergonomics reservations](rust-2024/match-ergonomics.md) - [Unsafe `extern` blocks](rust-2024/unsafe-extern.md) - - [Unsafe attributes](rust-2024/unsafe-attributes.md) + - [アンセーフなアトリビュート](rust-2024/unsafe-attributes.md) - [`unsafe_op_in_unsafe_fn` warning](rust-2024/unsafe-op-in-unsafe-fn.md) - [Disallow references to `static mut`](rust-2024/static-mut-references.md) - [Never type fallback change](rust-2024/never-type-fallback.md) diff --git a/src/rust-2024/unsafe-attributes.md b/src/rust-2024/unsafe-attributes.md new file mode 100644 index 0000000..ab13a94 --- /dev/null +++ b/src/rust-2024/unsafe-attributes.md @@ -0,0 +1,183 @@ + + +# アンセーフなアトリビュート + + + +## 概要 + + +- 以下のアトリビュートに `unsafe` が必要になりました。 + - [`export_name`] + - [`link_section`] + - [`no_mangle`] + + + +[`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 + + + +## 詳細 + + + +Rust 1.82 から全エディションにおいて、アトリビュートが健全性要件の遵守を要する場合に `unsafe` を付与する機能が追加されました。[^RFC3325] +アンセーフなアトリビュートは以下のように使用します。 + + + +```rust +// SAFETY: 同名のグローバル関数は他に存在しない +#[unsafe(no_mangle)] +pub fn example() {} +``` + + + +アトリビュートが `unsafe` だと宣言することで、遵守されるべき安全性要件があって、それをコンパイラが保証できないことが明示できます。 + + + +2024 エディションから、上記のアトリビュートを `unsafe` とすることが必須となります。 +これらが実際に遵守すべき安全性要件を以降に示します。 + + + +[^RFC3325]: 元の提案は [RFC 3325](https://rust-lang.github.io/rfcs/3325-unsafe-attributes.html) を参照のこと。 + + + +### 安全性要件 + + + +アトリビュート [`no_mangle`]、[`export_name`]、[`link_section`] はシンボル名とリンク動作を左右します。 +これらのアトリビュートを正しく使用するには注意を要します。 + + + +リンクされるシンボルの名前空間は全ライブラリで共有なので、ライブラリ間でシンボル名が衝突すると困ります。 +普通に定義された関数は、[シンボルのマングリング]のおかげで基本的に名前の衝突を気にする必要はありませんが、`export_name` アトリビュートなどは名前衝突を引き起こす可能性があります。 + + + +例えば、以下のコードはアンセーフなものがどこにもありませんが、過去のエディションでは Unix 系の環境でクラッシュします。 + +```rust,no_run,edition2021 +fn main() { + println!("Hello, world!"); +} + +#[export_name = "malloc"] +fn foo() -> usize { 1 } +``` + + + +2024 エディションでは、これらのアトリビュートには `unsafe` をつける必要があり、シンボルが適切に定義される必要があることがはっきりします。 + + + +```rust,edition2024 +// SAFETY: loop というシンボルの定義は以下のみ +#[unsafe(export_name="loop")] +fn arduino_loop() { + // ... +} +``` + + + +[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 + + + +## 移行 + +The [`unsafe_attr_outside_unsafe`] lint can update these attributes to use the `unsafe(...)` format. The lint is part of the `rust-2024-compatibility` lint group which is included in the automatic edition migration. In order to migrate your code to be Rust 2024 Edition compatible, run: + +[`unsafe_attr_outside_unsafe`] リントで、上記のアトリビュートに `unsafe(...)` を付与できます。 +このリントは、自動エディション移行に含まれる `rust-2024-compatibility` リントグループの一部です。 +コードを Rust 2024 互換に移行するには、以下を実行します。 + +```sh +cargo fix --edition +``` + + + +ただし、自動移行ツールはアトリビュートの使用方法が正しいことを検証するわけではありません。 +それを保証するのは、変わらずプログラマの責任です。 + + + +変更の必要のあるアトリビュートを検出するリントを手動で有効化することもできます。 + + + +```rust +// クレートのトップレベルに以下を追加すると手動移行できる +#![warn(unsafe_attr_outside_unsafe)] +``` From a342888a7d05592d92fad5b195828f226120e263 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Thu, 20 Feb 2025 08:47:59 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=E3=80=8Cunsafe=5Fop=5Fin=5Funsafe=5Ffn=20?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=E3=80=8D=E3=82=92=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SUMMARY.md | 2 +- src/rust-2024/unsafe-op-in-unsafe-fn.md | 122 ++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/rust-2024/unsafe-op-in-unsafe-fn.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 54a2958..1389c3e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -120,7 +120,7 @@ - [Match ergonomics reservations](rust-2024/match-ergonomics.md) - [アンセーフな `extern` ブロック](rust-2024/unsafe-extern.md) - [アンセーフなアトリビュート](rust-2024/unsafe-attributes.md) - - [`unsafe_op_in_unsafe_fn` warning](rust-2024/unsafe-op-in-unsafe-fn.md) + - [`unsafe_op_in_unsafe_fn` 警告](rust-2024/unsafe-op-in-unsafe-fn.md) - [Disallow references to `static mut`](rust-2024/static-mut-references.md) - [Never type fallback change](rust-2024/never-type-fallback.md) - [Macro fragment specifiers](rust-2024/macro-fragment-specifiers.md) diff --git a/src/rust-2024/unsafe-op-in-unsafe-fn.md b/src/rust-2024/unsafe-op-in-unsafe-fn.md new file mode 100644 index 0000000..a9b80d7 --- /dev/null +++ b/src/rust-2024/unsafe-op-in-unsafe-fn.md @@ -0,0 +1,122 @@ + + +# unsafe_op_in_unsafe_fn 警告 + + + +## 概要 + +- The [`unsafe_op_in_unsafe_fn`] lint now warns by default. + This warning detects calls to unsafe operations in unsafe functions without an explicit unsafe block. + +- [`unsafe_op_in_unsafe_fn`] リントのデフォルトのレベルが警告になりました。 + アンセーフな関数中にアンセーフな操作を明示的な unsafe ブロックなしに呼び出した場合にこの警告が出ます。 + + + +[`unsafe_op_in_unsafe_fn`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#unsafe-op-in-unsafe-fn + + + +## 詳細 + + + +[`unsafe_op_in_unsafe_fn`] は、アンセーフな関数中に[アンセーフな操作]が行われているが、それが [`unsafe {}` ブロック][unsafe-block]で囲まれていないことを検出するリントです。 + +```rust +# #![warn(unsafe_op_in_unsafe_fn)] +unsafe fn get_unchecked(x: &[T], i: usize) -> &T { + x.get_unchecked(i) // WARNING: requires unsafe block + // (訳) 警告: unsafe ブロックが必要 +} +``` + + + +これに対処するには、アンセーフな操作をすべて `unsafe` ブロックで囲ってください。 + +```rust +# #![deny(unsafe_op_in_unsafe_fn)] +unsafe fn get_unchecked(x: &[T], i: usize) -> &T { + unsafe { x.get_unchecked(i) } +} +``` + + + +これは、アンセーフ関数内の意図しないアンセーフな操作を避けるためのものです。 +かつては、アンセーフ関数の `unsafe` というキーワードには二重の意味が込められていました。 +関数を **呼び出す** 操作がアンセーフであり、呼び出し側が満たすべき安全性要件が存在するという点と、 +関数内でアンセーフな操作ができるという点です。 +特に後者を `unsafe` ブロックなしで実行できることが危険すぎると判断され、この変更に至りました。 + + + +詳細情報や動機などは [RFC #2585] に詳しいです。 + + + +[アンセーフな操作]: https://doc.rust-lang.org/reference/unsafety.html +[unsafe-block]: https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks +[RFC #2585]: https://rust-lang.github.io/rfcs/2585-unsafe-block-in-unsafe-fn.html + + + +## 移行 + + + +[`unsafe_op_in_unsafe_fn`] リントは `rust-2024-compatibility` リントグループの一部です。 +以下を実行すると、コードを Rust 2024 互換に変換できます。 + +```sh +cargo fix --edition +``` + + + +あるいは、unsafe ブロックを追加すべき場所を見つけるために以下のように手動でリントを有効化したり、逆に `allow` としてリントを完全に無視することもできます。 + + + +```rust +// クレートのトップレベルに以下を追加すると手動移行できる +#![warn(unsafe_op_in_unsafe_fn)] +``` From 5e74f9f16ad9c8021b181bc6555899eb2cd625c9 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Sun, 23 Feb 2025 05:13:59 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=E7=BF=BB=E8=A8=B3=E3=82=92=E3=82=BB?= =?UTF-8?q?=E3=83=AB=E3=83=95=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/rust-2024/unsafe-attributes.md | 23 ++++++++++++----------- src/rust-2024/unsafe-extern.md | 20 ++++++++++---------- src/rust-2024/unsafe-op-in-unsafe-fn.md | 9 +++++---- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/rust-2024/unsafe-attributes.md b/src/rust-2024/unsafe-attributes.md index ab13a94..b9cc761 100644 --- a/src/rust-2024/unsafe-attributes.md +++ b/src/rust-2024/unsafe-attributes.md @@ -38,7 +38,7 @@ Rust 1.82 added the ability in all editions to mark certain attributes as `unsafe` to indicate that they have soundness requirements that must be upheld.[^RFC3325] The syntax for an unsafe attribute looks like this: --> -Rust 1.82 から全エディションにおいて、アトリビュートが健全性要件の遵守を要する場合に `unsafe` を付与する機能が追加されました。[^RFC3325] +Rust 1.82 から全エディションにおいて、アトリビュートが健全性要件の遵守を要する場合に `unsafe` と書ける機能が追加されました。[^RFC3325] アンセーフなアトリビュートは以下のように使用します。 -2024 エディションから、上記のアトリビュートを `unsafe` とすることが必須となります。 -これらが実際に遵守すべき安全性要件を以降に示します。 +2024 エディションからは、上記のアトリビュートを `unsafe` とすることが必須となります。 +実際に遵守すべき安全性要件を以下に説明します。 -アトリビュート [`no_mangle`]、[`export_name`]、[`link_section`] はシンボル名とリンク動作を左右します。 -これらのアトリビュートを正しく使用するには注意を要します。 +アトリビュート [`no_mangle`]、[`export_name`]、[`link_section`] はシンボル名とリンク動作に関わるため、細心の注意を払って使用しなくてはなりません。 -リンクされるシンボルの名前空間は全ライブラリで共有なので、ライブラリ間でシンボル名が衝突すると困ります。 -普通に定義された関数は、[シンボルのマングリング]のおかげで基本的に名前の衝突を気にする必要はありませんが、`export_name` アトリビュートなどは名前衝突を引き起こす可能性があります。 +リンクされるシンボルの名前空間は全ライブラリで共有なので、ライブラリ間でシンボル名が衝突すると問題が発生する可能性があります。 +通常の方法で定義された関数は、[シンボルのマングリング]のおかげで基本的に名前の衝突を気にする必要はありませんが、`export_name` といったアトリビュートを使うとそうはいかなくなります。 -例えば、以下のコードはアンセーフなものがどこにもありませんが、過去のエディションでは Unix 系の環境でクラッシュします。 +例えば、以下のコードは何もアンセーフと書いていませんが、過去のエディションでは Unix 系の環境でクラッシュします。 ```rust,no_run,edition2021 fn main() { @@ -113,7 +112,7 @@ fn foo() -> usize { 1 } In the 2024 Edition, it is now required to mark these attributes as unsafe to emphasize that it is required to ensure that the symbol is defined correctly: --> -2024 エディションでは、これらのアトリビュートには `unsafe` をつける必要があり、シンボルが適切に定義される必要があることがはっきりします。 +2024 エディションでは、上記のアトリビュートには `unsafe` をつける必要があり、シンボルが適切に定義される必要があることが明確になります。 -[symbol mangling]: https://doc.rust-lang.org/rustc/symbol-mangling/index.html +[シンボルのマングリング]: 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 -[`unsafe_attr_outside_unsafe`] リントで、上記のアトリビュートに `unsafe(...)` を付与できます。 +[`unsafe_attr_outside_unsafe`] リントで、上記のアトリビュートに `unsafe(...)` を自動付与できます。 このリントは、自動エディション移行に含まれる `rust-2024-compatibility` リントグループの一部です。 コードを Rust 2024 互換に移行するには、以下を実行します。 diff --git a/src/rust-2024/unsafe-extern.md b/src/rust-2024/unsafe-extern.md index 2c66e6f..87f81ac 100644 --- a/src/rust-2024/unsafe-extern.md +++ b/src/rust-2024/unsafe-extern.md @@ -20,7 +20,7 @@ [`extern` blocks]: ../../reference/items/external-blocks.html --> -[`extern` blocks]: https://doc.rust-lang.org/reference/items/external-blocks.html +[`extern` ブロック]: https://doc.rust-lang.org/reference/items/external-blocks.html -Rust 1.82 から、[`extern` ブロック]を `unsafe` キーワードとともに宣言できるようになりました。[^RFC3484] -`unsafe` と書くことで、シグネチャが正しいことを保証するのが `extern` ブロックを書いた人の責任であることが明確になります。 -シグネチャが正しくないと、未定義動作になってしまいます。 +Rust 1.82 から、全エディションで [`extern` ブロック]を `unsafe` キーワードとともに宣言できるようになりました。[^RFC3484] +`unsafe` と書くことで、`extern` を書いた人にシグネチャが正しいことを保証する責任があることが明確になります。 +シグネチャが正しくないと、未定義動作を引き起こしかねません。 -`extern` ブロックを `unsafe` とできるのに加え、`extern` ブロック内の個々のアイテムを `safe` か `unsafe` と明示できるようになりました。 -`safe` のついたアイテムは、`unsafe` ブロックなしに使用できます。 +`extern` ブロックを `unsafe` とできるのに加え、`extern` ブロック内の個々のアイテムを `safe` か `unsafe` と明示できます。 +`safe` のついたアイテムは、`unsafe` で囲まなくても使用できるようになります。 2024 エディション以降、`extern` ブロックには必ず `unsafe` を付与する必要があります。 -これは、extern 定義が遵守すべき安全性基準が存在するということを明確にするためです。 +これにより、extern 定義が遵守すべき安全性要件が存在するということが明確になることが期待されます。 -[^RFC3484]: 元の提案については [RFC 3484](https://github.com/rust-lang/rfcs/blob/master/text/3484-unsafe-extern-blocks.md) 参照のこと。 +[^RFC3484]: 元の提案については [RFC 3484](https://github.com/rust-lang/rfcs/blob/master/text/3484-unsafe-extern-blocks.md) を参照のこと。 -ただし、自動移行ツールは `extern` ブロックのシグネチャが正しいことを検証するわけではありません。 +ただし、自動移行ツールは、`extern` ブロックのシグネチャが正しいことを検証することはできません。 それを保証するのは、変わらずプログラマの責任です。 -変更の必要のある `unsafe` ブロックを検出するリントを手動で有効化することもできます。 +変更の必要がある `unsafe` ブロックを検出するリントを手動で有効化することもできます。 - [`unsafe_op_in_unsafe_fn`] リントのデフォルトのレベルが警告になりました。 - アンセーフな関数中にアンセーフな操作を明示的な unsafe ブロックなしに呼び出した場合にこの警告が出ます。 + アンセーフな関数中でアンセーフな操作を明示的な unsafe ブロックなしに呼び出した場合にこの警告が出ます。