-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stabilize #![feature(target_feature_11)]
#99767
Stabilize #![feature(target_feature_11)]
#99767
Conversation
@rustbot label T-lang needs-fcp |
This comment has been minimized.
This comment has been minimized.
@rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:
No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
Oops, I should probably have removed the |
@rfcbot cancel |
@oli-obk proposal cancelled. |
Tried to write up a stabilization report, feedback would be appreciated. |
3d7c5ad
to
ec98a1e
Compare
This comment has been minimized.
This comment has been minimized.
ec98a1e
to
ebbd8f8
Compare
how does this interact with type alias impl trait #![feature(target_feature_11, type_alias_impl_trait)]
type Foo = impl FnOnce() + Default;
#[target_feature(enable = "avx2")]
fn avx2() {}
#[target_feature(enable = "avx2")]
fn qux() {
let x: Foo = || avx2(); // currently errors cause the closure isn't `Default`.
} in #77688 it was decided against adding |
@lcnr I think this is analogous to something like this? unsafe fn unsf() {}
// This has some safety requirements...
unsafe fn foo() {
// ...which might be used in the closure here
let x: Foo = || unsf();
} I think calling Or something like fn bar() {
// check that some invariants are upheld before doing some unsafe
if !invariant_upheld { return; }
let x: Foo = || unsafe { unsf(); };
} Wouldn't it be surprising to be able to call This was raised in #77688 (comment) but I couldn't find a proposed solution/workaround. If there is one, would it be applicable here as well? |
While With target features the skip can be fully implicit (except for a
as I realized another issue with implementing I guess I am fine with stabilizing this then ^^ while it seems like a final nail in the coffin of |
👋 Hello, I'm writing this comment in this stabilization PR to notify you, the authors of this PR, that #100591 has been merged, which implemented a change in how features are stabilized. Your PR has been filed before the change, so will likely require modifications in order to comply with the new rules. I recommend you to:
That's it! The If you have any questions, feel free to drop by the zulip stream, or ping me directly in this PR's thread. Thanks! 👋 |
ebbd8f8
to
7001d17
Compare
Done! Thank you very much for the heads-up @est31 |
r? rust-lang/compiler |
cdb5b0c
to
b379d21
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me
…re-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 - rust-lang#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: rust-lang/reference#1181 --- cc tracking issue rust-lang#69098 r? `@ghost`
…re-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 - rust-lang#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: rust-lang/reference#1181 --- cc tracking issue rust-lang#69098 r? ``@ghost``
...Hm. I was not aware this had been FCP'd. We are aware that this makes downgrading feature levels a backwards incompatible change for targets, right? |
☀️ Test successful - checks-actions |
You mean when proposals like this get accepted, the "default" set of default-enabled target features shrinks and some code calling From testing the implementation, that seems to have been avoided by not having a default set of target features. Even if the target feature is enabled by default, code still must use unsafe. I wasn't involved much during implementation of this RFC so I can't comment on how intentional that was, but I vaguely remember a comment that they intentionally made the most restricted version, where there is also no implication between features that came after another, e.g. sse2 -> sse. Take this code (playground): #![feature(target_feature_11)]
#[target_feature(enable = "sse")] fn foo() {}
#[target_feature(enable = "sse")] fn bar() { foo(); }
fn main() {
#[cfg(target_feature = "sse")]
bar(); //~ERROR call to function with `#[target_feature]` is unsafe and requires unsafe function or block
} It will print the error as indicated. The test is written in a way that shows that Also note that downgrading of target requirements are breaking changes already, for example you could have code like: extern { fn fancy_fn_that_uses_sse(); }
fn main() {
#[cfg(target_feature = "sse")]
unsafe { fancy_fn_that_uses_sse(); }
#[cfg(not(target_feature = "sse"))]
compile_error!("sorry but we only have an sse using implementation of this!");
} It doesn't use In these scenarios I also think that compiler errors are preferable to runtime SIGILLs or worse. One could think about extending the |
Finished benchmarking commit (b583ede): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. |
…iler-errors Revert stabilization of `#![feature(target_feature_11)]` This reverts rust-lang#99767 due to the presence of bugs rust-lang#108645 and rust-lang#108646. cc `@joshtriplett` cc tracking issue rust-lang#69098 r? `@ghost`
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 theFn*
traits.However, calling them from other
#[target_feature]
functions with a superset of features is safe.Test cases
Tests for this feature can be found in
src/test/ui/rfcs/rfc-2396-target_feature-11/
.Edge cases
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 appropriateFn*
traits.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
target_feature_11
feature reference#1181cc tracking issue #69098
r? @ghost