rust
rust copied to clipboard
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.
// 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/
.
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.
#[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
@rustbot label T-lang needs-fcp
The job x86_64-gnu-llvm-12
failed! Check out the build log: (web) (plain)
Click to see the possible cause of the failure (guessed by this bot)
Compiling std_detect v0.1.5 (/checkout/library/stdarch/crates/std_detect)
Compiling object v0.26.2
Compiling miniz_oxide v0.4.0
Compiling addr2line v0.16.0
thread 'rustc' panicked at 'unexpected `def_kind` in `codegen_fn_attrs`: Const', compiler/rustc_typeck/src/collect.rs:2696:9
0: 0x7f366474553d - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h11237028a75a1850
1: 0x7f36647add78 - core::fmt::write::h75736d5168df1a59
2: 0x7f3664736641 - std::io::Write::write_fmt::h933f9eb9dcce85a1
2: 0x7f3664736641 - std::io::Write::write_fmt::h933f9eb9dcce85a1
3: 0x7f366474870e - std::panicking::default_hook::{{closure}}::h1f2a2c824eeeb999
4: 0x7f366474845e - std::panicking::default_hook::h2355862caad73260
5: 0x7f3665253514 - rustc_driver[e8d3c5195d92d990]::DEFAULT_HOOK::{closure#0}::{closure#0}
6: 0x7f3664748e81 - std::panicking::rust_panic_with_hook::h9876449947bbdc93
7: 0x7f3664748ca7 - std::panicking::begin_panic_handler::{{closure}}::hc72773511a05eeab
8: 0x7f3664745ae4 - std::sys_common::backtrace::__rust_end_short_backtrace::h1d84a51dfb3646b1
9: 0x7f3664748989 - rust_begin_unwind
10: 0x7f36646fc043 - core::panicking::panic_fmt::hafd4d056af53fd8f
11: 0x7f3665d9c181 - rustc_typeck[c0f26da51bbb1d6]::collect::codegen_fn_attrs
12: 0x7f3666d3fc0f - rustc_query_system[8525185271f8bf9]::query::plumbing::try_execute_query::<rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt, rustc_query_system[8525185271f8bf9]::query::caches::ArenaCache<rustc_span[61b6b3eff38f7b69]::def_id::DefId, rustc_middle[5d5fde75cb8d8c1d]::middle::codegen_fn_attrs::CodegenFnAttrs>>
13: 0x7f3666e3fb03 - rustc_query_system[8525185271f8bf9]::query::plumbing::get_query::<rustc_query_impl[d599c90e6b17ac17]::queries::codegen_fn_attrs, rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt>
14: 0x7f36669c8469 - <rustc_query_impl[d599c90e6b17ac17]::Queries as rustc_middle[5d5fde75cb8d8c1d]::ty::query::QueryEngine>::codegen_fn_attrs
15: 0x7f3665d9bb41 - rustc_typeck[c0f26da51bbb1d6]::collect::codegen_fn_attrs
16: 0x7f3666d3fc0f - rustc_query_system[8525185271f8bf9]::query::plumbing::try_execute_query::<rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt, rustc_query_system[8525185271f8bf9]::query::caches::ArenaCache<rustc_span[61b6b3eff38f7b69]::def_id::DefId, rustc_middle[5d5fde75cb8d8c1d]::middle::codegen_fn_attrs::CodegenFnAttrs>>
17: 0x7f3666e3fb03 - rustc_query_system[8525185271f8bf9]::query::plumbing::get_query::<rustc_query_impl[d599c90e6b17ac17]::queries::codegen_fn_attrs, rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt>
18: 0x7f36669c8469 - <rustc_query_impl[d599c90e6b17ac17]::Queries as rustc_middle[5d5fde75cb8d8c1d]::ty::query::QueryEngine>::codegen_fn_attrs
19: 0x7f366619e9a0 - <rustc_passes[e00a1a91b4b62704]::check_attr::CheckAttrVisitor>::check_attributes
20: 0x7f36661a1666 - <rustc_passes[e00a1a91b4b62704]::check_attr::CheckAttrVisitor as rustc_hir[73f5179f97ca72d1]::intravisit::Visitor>::visit_expr
21: 0x7f36661c6929 - rustc_hir[73f5179f97ca72d1]::intravisit::walk_item::<rustc_passes[e00a1a91b4b62704]::check_attr::CheckAttrVisitor>
22: 0x7f36661a132d - <rustc_passes[e00a1a91b4b62704]::check_attr::CheckAttrVisitor as rustc_hir[73f5179f97ca72d1]::intravisit::Visitor>::visit_item
23: 0x7f366612ec55 - <rustc_middle[5d5fde75cb8d8c1d]::hir::map::Map>::visit_item_likes_in_module::<rustc_passes[e00a1a91b4b62704]::check_attr::CheckAttrVisitor>
24: 0x7f36661a174b - rustc_passes[e00a1a91b4b62704]::check_attr::check_mod_attrs
25: 0x7f3666d71b82 - rustc_query_system[8525185271f8bf9]::query::plumbing::try_execute_query::<rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt, rustc_query_system[8525185271f8bf9]::query::caches::DefaultCache<rustc_span[61b6b3eff38f7b69]::def_id::LocalDefId, ()>>
26: 0x7f3666e3b534 - rustc_query_system[8525185271f8bf9]::query::plumbing::get_query::<rustc_query_impl[d599c90e6b17ac17]::queries::check_mod_attrs, rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt>
27: 0x7f36669b5d14 - <rustc_query_impl[d599c90e6b17ac17]::Queries as rustc_middle[5d5fde75cb8d8c1d]::ty::query::QueryEngine>::check_mod_attrs
28: 0x7f366540c8da - <rustc_middle[5d5fde75cb8d8c1d]::hir::map::Map>::for_each_module::<rustc_interface[5088e07ffcb5d140]::passes::analysis::{closure#0}::{closure#1}::{closure#0}>
29: 0x7f3665376dac - std[45ea6e04d395d00d]::panicking::try::<(), core[25bfd9c2f7020e11]::panic::unwind_safe::AssertUnwindSafe<rustc_interface[5088e07ffcb5d140]::passes::analysis::{closure#0}::{closure#1}>>
30: 0x7f366538c768 - <rustc_session[5b4d9c7979230222]::session::Session>::time::<(), rustc_interface[5088e07ffcb5d140]::passes::analysis::{closure#0}>
31: 0x7f3665385a26 - rustc_interface[5088e07ffcb5d140]::passes::analysis
32: 0x7f3666da8036 - rustc_query_system[8525185271f8bf9]::query::plumbing::try_execute_query::<rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt, rustc_query_system[8525185271f8bf9]::query::caches::DefaultCache<(), core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>>
33: 0x7f3666e83c52 - rustc_query_system[8525185271f8bf9]::query::plumbing::get_query::<rustc_query_impl[d599c90e6b17ac17]::queries::analysis, rustc_query_impl[d599c90e6b17ac17]::plumbing::QueryCtxt>
34: 0x7f366699e68e - <rustc_query_impl[d599c90e6b17ac17]::Queries as rustc_middle[5d5fde75cb8d8c1d]::ty::query::QueryEngine>::analysis
35: 0x7f36652b6904 - <rustc_interface[5088e07ffcb5d140]::passes::QueryContext>::enter::<rustc_driver[e8d3c5195d92d990]::run_compiler::{closure#1}::{closure#2}::{closure#3}, core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>
36: 0x7f366526d180 - <rustc_interface[5088e07ffcb5d140]::interface::Compiler>::enter::<rustc_driver[e8d3c5195d92d990]::run_compiler::{closure#1}::{closure#2}, core[25bfd9c2f7020e11]::result::Result<core[25bfd9c2f7020e11]::option::Option<rustc_interface[5088e07ffcb5d140]::queries::Linker>, rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>
37: 0x7f36652c3d0d - rustc_span[61b6b3eff38f7b69]::with_source_map::<core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>, rustc_interface[5088e07ffcb5d140]::interface::create_compiler_and_run<core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>, rustc_driver[e8d3c5195d92d990]::run_compiler::{closure#1}>::{closure#1}>
38: 0x7f366526dd3a - <scoped_tls[63604573309c1f00]::ScopedKey<rustc_span[61b6b3eff38f7b69]::SessionGlobals>>::set::<rustc_interface[5088e07ffcb5d140]::interface::run_compiler<core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>, rustc_driver[e8d3c5195d92d990]::run_compiler::{closure#1}>::{closure#0}, core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>
39: 0x7f36652c899f - std[45ea6e04d395d00d]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[5088e07ffcb5d140]::util::run_in_thread_pool_with_globals<rustc_interface[5088e07ffcb5d140]::interface::run_compiler<core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>, rustc_driver[e8d3c5195d92d990]::run_compiler::{closure#1}>::{closure#0}, core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>::{closure#0}, core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>
40: 0x7f36652bbc89 - <<std[45ea6e04d395d00d]::thread::Builder>::spawn_unchecked_<rustc_interface[5088e07ffcb5d140]::util::run_in_thread_pool_with_globals<rustc_interface[5088e07ffcb5d140]::interface::run_compiler<core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>, rustc_driver[e8d3c5195d92d990]::run_compiler::{closure#1}>::{closure#0}, core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>::{closure#0}, core[25bfd9c2f7020e11]::result::Result<(), rustc_errors[1b6d01a399cf82b6]::ErrorGuaranteed>>::{closure#1} as core[25bfd9c2f7020e11]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
41: 0x7f36647551e5 - std::sys::unix::thread::Thread::new::thread_start::ha6ddf8fc8884e2d9
42: 0x7f365eca4609 - start_thread
43: 0x7f36645b7133 - clone
44: 0x0 - <unknown>
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
note: rustc 1.64.0-nightly (addc6d82d 2022-07-26) running on x86_64-unknown-linux-gnu
note: compiler flags: --crate-type dylib --crate-type rlib -C prefer-dynamic -C opt-level=3 -C embed-bitcode=no -C codegen-units=1 -C debuginfo=0 -C debug-assertions=on -Z unstable-options -C symbol-mangling-version=legacy -Z unstable-options -Z unstable-options -Z macro-backtrace -C link-args=-Wl,-z,origin -C link-args=-Wl,-rpath,$ORIGIN/../lib -Z unstable-options -C split-debuginfo=off -C prefer-dynamic -C llvm-args=-import-instr-limit=10 -C embed-bitcode=yes -Z crate-attr=doc(html_root_url="https://doc.rust-lang.org/nightly/") -Z binary-dep-depinfo -Z force-unstable-if-unmarked
note: some of the compiler flags provided by cargo are hidden
query stack during panic:
query stack during panic:
#0 [codegen_fn_attrs] computing codegen attributes of `io::error::repr_bitpacked::kind_from_prim::_`
#1 [codegen_fn_attrs] computing codegen attributes of `io::error::repr_bitpacked::kind_from_prim::_::{closure#0}`
#2 [check_mod_attrs] checking attributes in module `io::error::repr_bitpacked`
#3 [analysis] running analysis passes on this crate
error: could not compile `std`
Build completed unsuccessfully in 0:03:55
@rfcbot merge
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:
- [ ] @Aaron1011
- [ ] @cjgillot
- [x] @cramertj
- [x] @davidtwco
- [x] @eddyb
- [x] @estebank
- [x] @joshtriplett
- [ ] @lcnr
- [ ] @matthewjasper
- [ ] @michaelwoerister
- [x] @nagisa
- [ ] @nikomatsakis
- [ ] @oli-obk
- [ ] @petrochenkov
- [ ] @pnkfelix
- [ ] @scottmcm
- [ ] @wesleywiser
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 T-compiler
label, sorry for the inconvenience
@rfcbot cancel
@oli-obk proposal cancelled.
Tried to write up a stabilization report, feedback would be appreciated.
The job x86_64-gnu-llvm-12
failed! Check out the build log: (web) (plain)
Click to see the possible cause of the failure (guessed by this bot)
Check compiletest suite=mir-opt mode=mir-opt (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
running 181 tests
i......................................i................................................ 88/181
........i...F...............................................i........................... 176/181
Some tests failed in compiletest suite=mir-opt mode=mir-opt host=x86_64-unknown-linux-gnu target=x86_64-unknown-linux-gnu
failures:
---- [mir-opt] src/test/mir-opt/inline/inline-compatibility.rs stdout ----
---- [mir-opt] src/test/mir-opt/inline/inline-compatibility.rs stdout ----
4 fn inlined_target_feature() -> () {
5 let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40
6 let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
- + scope 1 (inlined target_feature) { // at $DIR/inline-compatibility.rs:13:5: 13:21
+ + scope 1 (inlined target_feature) { // at $DIR/inline-compatibility.rs:12:5: 12:21
9
10 bb0: {
11 StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
12 - _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
13 - // mir::Constant
- - // + span: $DIR/inline-compatibility.rs:13:5: 13:19
+ - // + span: $DIR/inline-compatibility.rs:12:5: 12:19
15 - // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) }
17 -
thread '[mir-opt] src/test/mir-opt/inline/inline-compatibility.rs' panicked at 'Actual MIR output differs from expected MIR output /checkout/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff', src/tools/compiletest/src/runtest.rs:3513:25
failures:
[mir-opt] src/test/mir-opt/inline/inline-compatibility.rs
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 Default
for function types and closures but that decision wasn't "we will never add that impl in the future" so I do want something apart from closures aren't Default
from preventing the above example to work
@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 x
through Foo::default()
would be unsound?
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 x
through Default
?
This was raised in https://github.com/rust-lang/rust/pull/77688#issuecomment-725538587 but I couldn't find a proposed solution/workaround. If there is one, would it be applicable here as well?
While || unsafe { some_unsafe_fn() }
is now a safe function pointer which we could leak this way, we still need unsafe
somewhere to skip that boundary.
With target features the skip can be fully implicit (except for a #[target_feature(...)]
attribute on the function constraining the opaque type).
Wouldn't it be surprising to be able to call
x
throughDefault
?
as Foo
would need an explicit Default
bound, I think no ^^
I realized another issue with implementing Default
for closures automatically. In the future, we may uncover that an opaque type implements Default
using specialization, changing implicit impls of Default
to change currently sound APIs to be unsound, making this a breaking change.
I guess I am fine with stabilizing this then ^^ while it seems like a final nail in the coffin of Default
for closures and function definitions, there are already a few other nails.
:wave: Hello, I'm writing this comment in this stabilization PR to notify you, the authors of this PR, that https://github.com/rust-lang/rust/pull/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:
- rebase the PR onto latest master, so that uses of the placeholder are possible.
- replace the version numbers in the PR with the placeholder
CURRENT_RUSTC_VERSION
. For language changes, this means the version numbers inaccepted.rs
(example: 4caedbae869855a19ca49455e2cd338ae3b8c1ef). For library changes, this means thesince
fields (example e576a9b554f24a26c36c04b41c901636d190605b).
That's it! The CURRENT_RUSTC_VERSION
placeholder will, as part of the release process, be replaced with the version number that the PR merged for. It can be used anywhere in rust-lang/rust
, not just accepted.rs and the since fields.
If you have any questions, feel free to drop by the zulip stream, or ping me directly in this PR's thread. Thanks! :wave:
Done! Thank you very much for the heads-up @est31
:umbrella: The latest upstream changes (presumably #102306) made this pull request unmergeable. Please resolve the merge conflicts.
@LeSeulArtichaut what's the status of this?
Hey! It looks like you've submitted a new PR for the library teams!
If this PR contains changes to any rust-lang/rust
public library APIs then please comment with @rustbot label +T-libs-api -T-libs
to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.
Examples of T-libs-api
changes:
- Stabilizing library features
- Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
- Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
- Changing public documentation in ways that create new stability guarantees
- Changing observable runtime behavior of library APIs
@rfcbot merge
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:
- [x] @cramertj
- [x] @joshtriplett
- [x] @nikomatsakis
- [ ] @pnkfelix
- [ ] @scottmcm
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.
@rustbot ready
:umbrella: The latest upstream changes (presumably #98914) made this pull request unmergeable. Please resolve the merge conflicts.
@rfcbot resolved
:umbrella: The latest upstream changes (presumably #105667) made this pull request unmergeable. Please resolve the merge conflicts.
@rfcbot resolved
@nikomatsakis I'm guessing you meant @rfcbot reviewed
?
:bell: This is now entering its final comment period, as per the review above. :bell:
The final comment period, with a disposition to merge, as per the review above, is now complete.
As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.
This will be merged soon.
:umbrella: The latest upstream changes (presumably #105741) made this pull request unmergeable. Please resolve the merge conflicts.
r? compiler
r? rust-lang/compiler
The comment was resolved and @estebank approved it, so @bors r=estebank