Skip to content

Commit

Permalink
Rework the target_fature safety restrictions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ehuss committed Feb 7, 2025
1 parent e53d30b commit a28ead0
Showing 1 changed file with 46 additions and 17 deletions.
63 changes: 46 additions & 17 deletions src/attributes/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit a28ead0

Please sign in to comment.