about summary refs log tree commit diff
path: root/compiler/rustc_feature/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-02-28 01:14:56 +0000
committerbors <bors@rust-lang.org>2023-02-28 01:14:56 +0000
commitb583ede652936887a85c54bb793251479c82d3ee (patch)
tree9a63f51a9c07d77d35a17fb329d14c9b4ae04271 /compiler/rustc_feature/src
parent6290ae92b2df2bfff09abdcb80a3aa483692bab6 (diff)
parentb379d216eefaba083a0627b1724d73f99d4bdf5c (diff)
downloadrust-b583ede652936887a85c54bb793251479c82d3ee.tar.gz
rust-b583ede652936887a85c54bb793251479c82d3ee.zip
Auto merge of #99767 - LeSeulArtichaut:stable-target-feature-11, r=estebank
Stabilize `#![feature(target_feature_11)]`

## Stabilization report

### Summary

Allows for safe functions to be marked with `#[target_feature]` attributes.

Functions marked with `#[target_feature]` are generally considered as unsafe functions: they are unsafe to call, cannot be assigned to safe function pointers, and don't implement the `Fn*` traits.

However, calling them from other `#[target_feature]` functions with a superset of features is safe.

```rust
// Demonstration function
#[target_feature(enable = "avx2")]
fn avx2() {}

fn foo() {
    // Calling `avx2` here is unsafe, as we must ensure
    // that AVX is available first.
    unsafe {
        avx2();
    }
}

#[target_feature(enable = "avx2")]
fn bar() {
    // Calling `avx2` here is safe.
    avx2();
}
```

### Test cases

Tests for this feature can be found in [`src/test/ui/rfcs/rfc-2396-target_feature-11/`](https://github.com/rust-lang/rust/tree/b67ba9ba208ac918228a18321fc3a11a99b1c62b/src/test/ui/rfcs/rfc-2396-target_feature-11/).

### Edge cases

- https://github.com/rust-lang/rust/issues/73631

Closures defined inside functions marked with `#[target_feature]` inherit the target features of their parent function. They can still be assigned to safe function pointers and implement the appropriate `Fn*` traits.

```rust
#[target_feature(enable = "avx2")]
fn qux() {
    let my_closure = || avx2(); // this call to `avx2` is safe
    let f: fn() = my_closure;
}
```

This means that in order to call a function with `#[target_feature]`, you must show that the target-feature is available while the function executes *and* for as long as whatever may escape from that function lives.

### Documentation

- Reference: https://github.com/rust-lang/reference/pull/1181

---
cc tracking issue #69098
r? `@ghost`
Diffstat (limited to 'compiler/rustc_feature/src')
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
2 files changed, 2 insertions, 2 deletions
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index e064e87a59a..2d80c15589d 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -312,6 +312,8 @@ declare_features! (
     (accepted, struct_variant, "1.0.0", None, None),
     /// Allows `#[target_feature(...)]`.
     (accepted, target_feature, "1.27.0", None, None),
+    /// Allows the use of `#[target_feature]` on safe functions.
+    (accepted, target_feature_11, "CURRENT_RUSTC_VERSION", Some(69098), None),
     /// Allows `fn main()` with return types which implements `Termination` (RFC 1937).
     (accepted, termination_trait, "1.26.0", Some(43301), None),
     /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 6d8f7e4a0f6..c694502e016 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -513,8 +513,6 @@ declare_features! (
     (active, strict_provenance, "1.61.0", Some(95228), None),
     /// Allows string patterns to dereference values to match them.
     (active, string_deref_patterns, "1.67.0", Some(87121), None),
-    /// Allows the use of `#[target_feature]` on safe functions.
-    (active, target_feature_11, "1.45.0", Some(69098), None),
     /// Allows using `#[thread_local]` on `static` items.
     (active, thread_local, "1.0.0", Some(29594), None),
     /// Allows defining `trait X = A + B;` alias items.