Skip to content

Commit a28ead0

Browse files
committed
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.
1 parent e53d30b commit a28ead0

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

Diff for: src/attributes/codegen.md

+46-17
Original file line numberDiff line numberDiff line change
@@ -87,23 +87,52 @@ that is not supported on the current platform the code is running on, *except*
8787
if the platform explicitly documents this to be safe.
8888

8989
r[attributes.codegen.target_feature.safety-restrictions]
90-
Because of this, on many platforms the following restrictions apply:
91-
92-
- `#[target_feature]` functions (and closures that inherit the attribute)
93-
can only be safely called within caller that enable all the `target_feature`s
94-
that the callee enables.
95-
- `#[target_feature]` functions (and closures that inherit the attribute)
96-
can only be coerced to *safe* `fn` pointers in contexts that enable all the
97-
`target_feature`s that the coercee enables.
98-
- `#[target_feature]` functions *never* implement `Fn` traits, although
99-
closures inheriting features from the enclosing function do.
100-
101-
Moreover, since Rust needs to be able to check the usage of `#[target_feature]`
102-
functions at callsites to ensure safety, safe functions for which this check
103-
would not be possible cannot be annotated with this attribute. This includes:
104-
105-
- `main`
106-
- other special functions that allow safe functions such as `#[panic_handler]`
90+
The following restrictions apply unless otherwise specified by the platform rules below:
91+
92+
- 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.
93+
This restriction does not apply in an `unsafe` context.
94+
- 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.
95+
This restriction does not apply to `unsafe` function pointers.
96+
97+
Implicitly enabled features are included in this rule. For example an `sse2` function can call ones marked with `sse`.
98+
99+
```rust
100+
# #[cfg(target_feature = "avx2")] {
101+
#[target_feature(enable = "avx")]
102+
fn foo_avx() {}
103+
104+
fn bar() {
105+
// Calling `foo_avx` here is unsafe, as we must ensure that AVX is
106+
// available first, even if `avx` is enabled by default on the target
107+
// platform or manually enabled as compiler flags.
108+
unsafe {
109+
foo_avx();
110+
}
111+
}
112+
113+
#[target_feature(enable = "avx")]
114+
fn bar_avx() {
115+
// Calling `foo_avx` here is safe.
116+
foo_avx();
117+
|| foo_avx();
118+
}
119+
120+
#[target_feature(enable = "avx2")]
121+
fn bar_avx2() {
122+
// Calling `foo_avx` here is safe because `avx2` implies `avx`.
123+
foo_avx();
124+
}
125+
# }
126+
```
127+
128+
r[attributes.codegen.target_feature.fn-traits]
129+
A function with a `#[target_feature]` attribute *never* implements the `Fn` family of traits, although closures inheriting features from the enclosing function do.
130+
131+
r[attributes.codegen.target_feature.allowed-positions]
132+
The `#[target_feature]` attribute is not allowed on the following places:
133+
134+
- [the `main` function][crate.main]
135+
- a [`panic_handler` function][runtime.panic_handler]
107136
- safe trait methods
108137
- safe default functions in traits
109138

0 commit comments

Comments
 (0)