From 3ced4dbfb8d98361e3cf3deb9a30beade163d17a Mon Sep 17 00:00:00 2001 From: Luca Versari Date: Fri, 24 Jan 2025 11:24:03 +0100 Subject: [PATCH 1/5] Update reference for target_feature_11. --- src/attributes/codegen.md | 51 +++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index ab9295c3b..83a084229 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -69,7 +69,7 @@ features. It uses the [_MetaListNameValueStr_] syntax with a single key of ```rust # #[cfg(target_feature = "avx2")] #[target_feature(enable = "avx2")] -unsafe fn foo_avx2() {} +fn foo_avx2() {} ``` r[attributes.codegen.target_feature.arch] @@ -77,11 +77,37 @@ Each [target architecture] has a set of features that may be enabled. It is an error to specify a feature for a target architecture that the crate is not being compiled for. +r[attributes.codegen.target_feature.closures] +Closures defined within a `target_feature`-annotated function inherit the +attribute from the enclosing function. + r[attributes.codegen.target_feature.target-ub] It is [undefined behavior] to call a function that is compiled with a feature that is not supported on the current platform the code is running on, *except* if the platform explicitly documents this to be safe. +r[attributes.codegen.target_feature.safety-restrictions] +Because of this, on many platforms the following restrictions apply: + +- `#[target_feature]` functions (and closures that inherit the attribute) + can only be safely called within caller that enable all the `target_feature`s + that the callee enables. +- `#[target_feature]` functions (and closures that inherit the attribute) + can only be coerced to *safe* `fn` pointers in contexts that enable all the + `target_feature`s that the coercee enables. +- `#[target_feature]` functions *never* implement `Fn` traits, although + closures inheriting features from the enclosing function do. + +Moreover, since Rust needs to be able to check the usage of `#[target_feature]` +functions at callsites to ensure safety, safe functions for which this check +would not be possible cannot be annotated with this attribute. This includes: + +- `main` +- other special functions that allow safe functions such as `#[panic_handler]` +- safe trait methods +- safe default functions in traits + + r[attributes.codegen.target_feature.inline] Functions marked with `target_feature` are not inlined into a context that does not support the given features. The `#[inline(always)]` attribute may not @@ -98,8 +124,8 @@ r[attributes.codegen.target_feature.x86] Executing code with unsupported features is undefined behavior on this platform. -Hence this platform requires that `#[target_feature]` is only applied to [`unsafe` -functions][unsafe function]. +Hence on this platform usage of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. Feature | Implicitly Enables | Description ------------|--------------------|------------------- @@ -166,8 +192,8 @@ r[attributes.codegen.target_feature.aarch64] #### `aarch64` -This platform requires that `#[target_feature]` is only applied to [`unsafe` -functions][unsafe function]. +On this platform the usage of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. Further documentation on these features can be found in the [ARM Architecture Reference Manual], or elsewhere on [developer.arm.com]. @@ -231,8 +257,8 @@ r[attributes.codegen.target_feature.riscv] #### `riscv32` or `riscv64` -This platform requires that `#[target_feature]` is only applied to [`unsafe` -functions][unsafe function]. +On this platform the usage of `#[target_feature]` functions follows the +[above restrictions][attributes.codegen.target_feature.safety-restrictions]. Further documentation on these features can be found in their respective specification. Many specifications are described in the [RISC-V ISA Manual] or @@ -293,12 +319,11 @@ r[attributes.codegen.target_feature.wasm] #### `wasm32` or `wasm64` -`#[target_feature]` may be used with both safe and -[`unsafe` functions][unsafe function] on Wasm platforms. It is impossible to -cause undefined behavior via the `#[target_feature]` attribute because -attempting to use instructions unsupported by the Wasm engine will fail at load -time without the risk of being interpreted in a way different from what the -compiler expected. +Safe `#[target_feature]` functions may always be used in safe contexts on Wasm +platforms. It is impossible to cause undefined behavior via the +`#[target_feature]` attribute because attempting to use instructions +unsupported by the Wasm engine will fail at load time without the risk of being +interpreted in a way different from what the compiler expected. Feature | Implicitly Enables | Description ----------------------|---------------------|------------------- From ec933d32af1b6a80556c0c2eb99218a36ebc1ef7 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 6 Feb 2025 19:27:31 -0800 Subject: [PATCH 2/5] Add target_feature to unsafety list --- src/unsafety.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/unsafety.md b/src/unsafety.md index 6878bbd8a..352edec47 100644 --- a/src/unsafety.md +++ b/src/unsafety.md @@ -21,6 +21,9 @@ r[safety.unsafe-union-access] r[safety.unsafe-call] - Calling an unsafe function (including an intrinsic or foreign function). +r[safety.unsafe-target-feature-call] +- Calling a safe function marked with a [`target_feature`][attributes.codegen.target_feature] from a function that does not have a `target_feature` attribute enabling the same features (see [attributes.codegen.target_feature.safety-restrictions]). + r[safety.unsafe-impl] - Implementing an [unsafe trait]. From 8b4a45c9be2073fbd1425248c6effe32346f6768 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 6 Feb 2025 19:28:26 -0800 Subject: [PATCH 3/5] Reward the `unsafe` block to be more general The `unsafe` block enables several abilities beyond just calling unsafe functions and dereferencing pointers. Link to the actual list of things you can do. --- src/unsafe-keyword.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/unsafe-keyword.md b/src/unsafe-keyword.md index 2443e65c6..b69e91062 100644 --- a/src/unsafe-keyword.md +++ b/src/unsafe-keyword.md @@ -27,7 +27,7 @@ r[unsafe.block] ## Unsafe blocks (`unsafe {}`) r[unsafe.block.intro] -A block of code can be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions or dereferencing raw pointers. +A block of code can be prefixed with the `unsafe` keyword to permit using the unsafe actions as defined in the [Unsafety] chapter, such as calling other unsafe functions or dereferencing raw pointers. r[unsafe.block.fn-body] By default, the body of an unsafe function is also considered to be an unsafe block; @@ -48,6 +48,8 @@ For example, a doubly-linked list is not a tree structure and can only be repres By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented without reference counting. (See ["Learn Rust With Entirely Too Many Linked Lists"](https://rust-unofficial.github.io/too-many-lists/) for a more in-depth exploration of this particular example.) +[Unsafety]: unsafety.md + r[unsafe.trait] ## Unsafe traits (`unsafe trait`) From e53d30b84ea3ee3ab5ac31247613e7076a090a96 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 6 Feb 2025 19:29:02 -0800 Subject: [PATCH 4/5] Clean up the markdown --- src/attributes/codegen.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 83a084229..5fabfa6a5 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -107,7 +107,6 @@ would not be possible cannot be annotated with this attribute. This includes: - safe trait methods - safe default functions in traits - r[attributes.codegen.target_feature.inline] Functions marked with `target_feature` are not inlined into a context that does not support the given features. The `#[inline(always)]` attribute may not @@ -495,7 +494,6 @@ trait object whose methods are attributed. [target architecture]: ../conditional-compilation.md#target_arch [trait]: ../items/traits.md [undefined behavior]: ../behavior-considered-undefined.md -[unsafe function]: ../unsafe-keyword.md [rust-abi]: ../items/external-blocks.md#abi [`Location`]: core::panic::Location From a28ead011c5a5cbd09805f9c1dbb75a64231ed11 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 6 Feb 2025 19:33:28 -0800 Subject: [PATCH 5/5] Rework the target_fature safety restrictions This does some rewording to try to make things a little more explicit and clearer: - Moves the `Fn` traits to a separate rule, it wasn't directly related to what is safe and not safe. - Moves the allowed positions into a separate rule, and adds some links to those. I dropped the "other special functions" because it is not defined anywhere. - Add an example. - Add a remark about implicit features. - Don't say "on many platforms", and be more explicit about how this is overridden. - Various rewording for clarity. - Remove word wrapping. --- src/attributes/codegen.md | 63 ++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 5fabfa6a5..b9a24b8a7 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -87,23 +87,52 @@ that is not supported on the current platform the code is running on, *except* if the platform explicitly documents this to be safe. r[attributes.codegen.target_feature.safety-restrictions] -Because of this, on many platforms the following restrictions apply: - -- `#[target_feature]` functions (and closures that inherit the attribute) - can only be safely called within caller that enable all the `target_feature`s - that the callee enables. -- `#[target_feature]` functions (and closures that inherit the attribute) - can only be coerced to *safe* `fn` pointers in contexts that enable all the - `target_feature`s that the coercee enables. -- `#[target_feature]` functions *never* implement `Fn` traits, although - closures inheriting features from the enclosing function do. - -Moreover, since Rust needs to be able to check the usage of `#[target_feature]` -functions at callsites to ensure safety, safe functions for which this check -would not be possible cannot be annotated with this attribute. This includes: - -- `main` -- other special functions that allow safe functions such as `#[panic_handler]` +The following restrictions apply unless otherwise specified by the platform rules below: + +- Safe `#[target_feature]` functions (and closures that inherit the attribute) can only be safely called within a caller that enables all the `target_feature`s that the callee enables. + This restriction does not apply in an `unsafe` context. +- Safe `#[target_feature]` functions (and closures that inherit the attribute) can only be coerced to *safe* function pointers in contexts that enable all the `target_feature`s that the coercee enables. + This restriction does not apply to `unsafe` function pointers. + +Implicitly enabled features are included in this rule. For example an `sse2` function can call ones marked with `sse`. + +```rust +# #[cfg(target_feature = "avx2")] { +#[target_feature(enable = "avx")] +fn foo_avx() {} + +fn bar() { + // Calling `foo_avx` here is unsafe, as we must ensure that AVX is + // available first, even if `avx` is enabled by default on the target + // platform or manually enabled as compiler flags. + unsafe { + foo_avx(); + } +} + +#[target_feature(enable = "avx")] +fn bar_avx() { + // Calling `foo_avx` here is safe. + foo_avx(); + || foo_avx(); +} + +#[target_feature(enable = "avx2")] +fn bar_avx2() { + // Calling `foo_avx` here is safe because `avx2` implies `avx`. + foo_avx(); +} +# } +``` + +r[attributes.codegen.target_feature.fn-traits] +A function with a `#[target_feature]` attribute *never* implements the `Fn` family of traits, although closures inheriting features from the enclosing function do. + +r[attributes.codegen.target_feature.allowed-positions] +The `#[target_feature]` attribute is not allowed on the following places: + +- [the `main` function][crate.main] +- a [`panic_handler` function][runtime.panic_handler] - safe trait methods - safe default functions in traits