@@ -224,23 +224,34 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
224
224
if !tcx. is_closure ( did. to_def_id ( ) )
225
225
&& tcx. fn_sig ( did) . skip_binder ( ) . unsafety ( ) == hir:: Unsafety :: Normal
226
226
{
227
- // The `#[target_feature]` attribute is allowed on
228
- // WebAssembly targets on all functions, including safe
229
- // ones. Other targets have conditions on the usage of
230
- // `#[target_feature]` because on most targets
231
- // execution of instructions that are not supported is
232
- // considered undefined behavior. For WebAssembly which is a
233
- // 100% safe target at execution time it's not possible to
234
- // execute undefined instructions, and even if a future
235
- // feature was added in some form for this it would be a
236
- // deterministic trap. There is no undefined behavior when
237
- // executing WebAssembly so `#[target_feature]` is allowed
238
- // on safe functions (but again, only for WebAssembly)
239
- //
240
- // Note that this is also allowed if `actually_rustdoc` so
241
- // if a target is documenting some wasm-specific code then
242
- // it's not spuriously denied.
243
- if !( tcx. sess . target . is_like_wasm || tcx. sess . opts . actually_rustdoc ) {
227
+ if tcx. sess . target . is_like_wasm || tcx. sess . opts . actually_rustdoc {
228
+ // The `#[target_feature]` attribute is allowed on
229
+ // WebAssembly targets on all functions, including safe
230
+ // ones. Other targets require that `#[target_feature]` is
231
+ // only applied to unsafe functions (pending the
232
+ // `target_feature_11` feature) because on most targets
233
+ // execution of instructions that are not supported is
234
+ // considered undefined behavior. For WebAssembly which is a
235
+ // 100% safe target at execution time it's not possible to
236
+ // execute undefined instructions, and even if a future
237
+ // feature was added in some form for this it would be a
238
+ // deterministic trap. There is no undefined behavior when
239
+ // executing WebAssembly so `#[target_feature]` is allowed
240
+ // on safe functions (but again, only for WebAssembly)
241
+ //
242
+ // Note that this is also allowed if `actually_rustdoc` so
243
+ // if a target is documenting some wasm-specific code then
244
+ // it's not spuriously denied.
245
+ } else if !tcx. features ( ) . target_feature_11 {
246
+ let mut err = feature_err (
247
+ & tcx. sess . parse_sess ,
248
+ sym:: target_feature_11,
249
+ attr. span ,
250
+ "`#[target_feature(..)]` can only be applied to `unsafe` functions" ,
251
+ ) ;
252
+ err. span_label ( tcx. def_span ( did) , "not an `unsafe` function" ) ;
253
+ err. emit ( ) ;
254
+ } else {
244
255
check_target_feature_trait_unsafe ( tcx, did, attr. span ) ;
245
256
}
246
257
}
@@ -467,7 +478,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
467
478
} ) ;
468
479
469
480
// #73631: closures inherit `#[target_feature]` annotations
470
- if tcx. is_closure ( did. to_def_id ( ) ) {
481
+ if tcx. features ( ) . target_feature_11 && tcx . is_closure ( did. to_def_id ( ) ) {
471
482
let owner_id = tcx. parent ( did. to_def_id ( ) ) ;
472
483
if tcx. def_kind ( owner_id) . has_codegen_attrs ( ) {
473
484
codegen_fn_attrs
0 commit comments