Change:
This example currently gives an error (): Should it? made the case that, once you enter , you have demonstrated that the target feature is present on your system, so it would make sense for closures declared within that item to "inherit" the target features from their enclosing function items (i.e., be able to invoke target-feature functions that require them, and probably also get the attributes declared within LLVM). Some questions: Is there some notion of "scoped" target features? i.e., as the example demonstrates, this allows target-feature functions to "escape" into the wider world, is that a problem? If closures do inherit, should they still be considered to implement etc? (See ) Would we want the ability to explicitly annotate closures with ? If so, that would presumably mean that explicitly annotated closures cannot* implement , which might be surprising and non-obvious.
cc
I have run into boxed closures performing poorly, it isn't obvious that something like this would be exceptionally slow--orders of magnitude worse than the naive version since each intrinsic results in a : Not related to closures, but inheriting features, should creating function pointers be allowed as well? For example:
I think any performance implications of boxing are pretty orthogonal to the question at hand. The question of coercing to a fn pointer, though, is pretty germane. I think that should probably be supported, yes, by the same logic. (I guess it would be unsafe to do outside of a suitable target-feature function?)
Sorry if I was unclear--I was referring to the fact that the intrinsics fail to inline into the closure despite it appearing within a target-feature function, unrelated to the implication of boxing the closure. Pre-target-feature-1.1 this is particularly non-obvious because the block is always required and there is no indication that the closure isn't inheriting the features.
fcp merge Having heard no objections, I'd like to call this to question. Dear I propose that we make the change described in the OP for the reasons that were outlined there.
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [x] [ ] 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 for info about what commands tagged team members can give me.
Discussed this in our meeting today. Notes from our minutes: Assumption that this makes is that once you run code with a given target feature, you will always have that target feature available. In theory you could have some complex architecture where you have asymmetric multiprocessing that has distinct capabilities: But this would break a huge amount of code in the wild that assumes you can check the CPUID once and then cache that result. There has been discussion in the linux community that in such a scenario, you would get back the universal subset available, and would have to “opt in” to observing features that are specific to your sort of core. New type of UB: “taking a target feature away from your process after having run code that uses that target feature is UB”. We could change this in the future if we need to deal with complex asymmetric multiprocessing scenarios as described above. Definition of the unsafe proof obligation to call a target-feature: You must show that the target-feature is available while the function executes and whatever may escape from that function. This emphasized condition is trivial in the case where cpu features never change. In a hybrid architecture where cpu features can change, you would have to know whether fn and closure pointers escape and for how long. This may imply new annotations that assure you that they do not escape or perhaps adding a lifetime annotation. Lifetime annotations could also be useful for dynamic loading/unloading scenarios where functions get unloaded.
Ping and -- checkbox
I was also expecting inner functions to inherit the target-feature annotations of the outer function. Can this question fit here or does it warrant a separate issue?
I'm sorry, I'm not sure I understand everything at hand, but would this not implicitly resolve 's question about the Rust calling convention / ABI in favor of yes? Or at least move it much closer to, thus bringing a soundness hole closer to resolution?
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , 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. The RFC will be merged soon.

Discussion:
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::IntTypeExt; <del> use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt}; </del> <ins> use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt}; </ins> use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness}; use rustc_session::config::SanitizerSet; use rustc_session::lint;

} }); <ins> // #73631: closures inherit `#[target_feature]` annotations if tcx.features().target_feature_11 && tcx.is_closure(id) { let owner_id = tcx.parent(id).expect("closure should have a parent"); codegen_fn_attrs .target_features .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied()) } </ins> // If a function uses #[target_feature] it can't be inlined into general // purpose functions as they wouldn't have the right target features // enabled. For that reason we also forbid #[inline(always)] as it can't be

<ins> // Tests #73631: closures inherit `#[target_feature]` annotations // check-pass // only-x86_64 #![feature(target_feature_11)] #[target_feature(enable="avx")] fn also_use_avx() { println!("Hello from AVX") } #[target_feature(enable="avx")] fn use_avx() -> Box<dyn Fn()> { Box::new(|| also_use_avx()) } fn main() {} </ins>