1- use rustc_ast:: { ast , attr , MetaItemKind , NestedMetaItem } ;
2- use rustc_attr:: { list_contains_name , InlineAttr , InstructionSetAttr , OptimizeAttr } ;
1+ use rustc_ast:: { MetaItemKind , NestedMetaItem , ast , attr } ;
2+ use rustc_attr:: { InlineAttr , InstructionSetAttr , OptimizeAttr , list_contains_name } ;
33use rustc_errors:: codes:: * ;
4- use rustc_errors:: { struct_span_code_err , DiagMessage , SubdiagMessage } ;
4+ use rustc_errors:: { DiagMessage , SubdiagMessage , struct_span_code_err } ;
55use rustc_hir as hir;
66use rustc_hir:: def:: DefKind ;
7- use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
7+ use rustc_hir:: def_id:: { DefId , LOCAL_CRATE , LocalDefId } ;
88use rustc_hir:: weak_lang_items:: WEAK_LANG_ITEMS ;
9- use rustc_hir:: { lang_items , LangItem } ;
9+ use rustc_hir:: { LangItem , lang_items } ;
1010use rustc_middle:: middle:: codegen_fn_attrs:: {
1111 CodegenFnAttrFlags , CodegenFnAttrs , PatchableFunctionEntry , TargetFeature ,
1212} ;
@@ -16,8 +16,8 @@ use rustc_middle::ty::{self as ty, Ty, TyCtxt};
1616use rustc_session:: lint;
1717use rustc_session:: parse:: feature_err;
1818use rustc_span:: symbol:: Ident ;
19- use rustc_span:: { sym , Span } ;
20- use rustc_target:: spec:: { abi , SanitizerSet } ;
19+ use rustc_span:: { Span , sym } ;
20+ use rustc_target:: spec:: { SanitizerSet , abi } ;
2121
2222use crate :: errors;
2323use crate :: target_features:: { check_target_feature_trait_unsafe, from_target_feature} ;
@@ -82,11 +82,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
8282 use DefKind :: * ;
8383
8484 let def_kind = tcx. def_kind ( did) ;
85- if let Fn | AssocFn | Variant | Ctor ( ..) = def_kind {
86- Some ( tcx. fn_sig ( did) )
87- } else {
88- None
89- }
85+ if let Fn | AssocFn | Variant | Ctor ( ..) = def_kind { Some ( tcx. fn_sig ( did) ) } else { None }
9086 } ;
9187
9288 for attr in attrs. iter ( ) {
@@ -253,7 +249,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
253249 && let Some ( fn_sig) = fn_sig ( )
254250 && fn_sig. skip_binder ( ) . safety ( ) == hir:: Safety :: Safe
255251 {
256- if tcx. sess . target . is_like_wasm || tcx. sess . opts . actually_rustdoc {
252+ if attr. meta_item_list ( ) . is_some_and ( |list| {
253+ list. len ( ) == 1 && list[ 0 ] . ident ( ) . is_some_and ( |x| x. name == sym:: from_args)
254+ } ) {
255+ // #[target_feature(from_args)] can be applied to safe functions and safe
256+ // trait methods.
257+ } else if tcx. sess . target . is_like_wasm || tcx. sess . opts . actually_rustdoc {
257258 // The `#[target_feature]` attribute is allowed on
258259 // WebAssembly targets on all functions, including safe
259260 // ones. Other targets require that `#[target_feature]` is
@@ -292,6 +293,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
292293 attr,
293294 supported_target_features,
294295 & mut codegen_fn_attrs. target_features ,
296+ Some ( & mut codegen_fn_attrs. target_features_from_args ) ,
295297 ) ;
296298 }
297299 sym:: linkage => {
@@ -602,7 +604,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
602604 }
603605 }
604606
605- if let Some ( sig) = fn_sig_outer ( ) {
607+ if let Some ( sig) = fn_sig_outer ( )
608+ && codegen_fn_attrs. target_features_from_args
609+ {
606610 let mut additional_tf = vec ! [ ] ;
607611 for ty in sig. skip_binder ( ) . inputs ( ) . skip_binder ( ) {
608612 extend_with_struct_target_features (
@@ -769,7 +773,7 @@ fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeatur
769773 let mut features = vec ! [ ] ;
770774 let supported_features = tcx. supported_target_features ( LOCAL_CRATE ) ;
771775 for attr in tcx. get_attrs ( def_id, sym:: target_feature) {
772- from_target_feature ( tcx, attr, supported_features, & mut features) ;
776+ from_target_feature ( tcx, attr, supported_features, & mut features, None ) ;
773777 }
774778 tcx. arena . alloc_slice ( & features)
775779}
0 commit comments