11use rustc_ast:: { ast, attr, MetaItemKind , NestedMetaItem } ;
22use rustc_attr:: { list_contains_name, InlineAttr , InstructionSetAttr , OptimizeAttr } ;
3- use rustc_data_structures:: fx:: FxHashSet ;
43use rustc_errors:: codes:: * ;
54use rustc_errors:: { struct_span_code_err, DiagMessage , SubdiagMessage } ;
65use rustc_hir as hir;
@@ -9,7 +8,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
98use rustc_hir:: weak_lang_items:: WEAK_LANG_ITEMS ;
109use rustc_hir:: { lang_items, LangItem } ;
1110use rustc_middle:: middle:: codegen_fn_attrs:: {
12- CodegenFnAttrFlags , CodegenFnAttrs , PatchableFunctionEntry , TargetFeature ,
11+ CodegenFnAttrFlags , CodegenFnAttrs , PatchableFunctionEntry ,
1312} ;
1413use rustc_middle:: mir:: mono:: Linkage ;
1514use rustc_middle:: query:: Providers ;
@@ -18,7 +17,6 @@ use rustc_session::lint;
1817use rustc_session:: parse:: feature_err;
1918use rustc_span:: symbol:: Ident ;
2019use rustc_span:: { sym, Span } ;
21- use rustc_target:: abi:: VariantIdx ;
2220use rustc_target:: spec:: { abi, SanitizerSet } ;
2321
2422use crate :: errors;
@@ -80,26 +78,23 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
8078 let mut link_ordinal_span = None ;
8179 let mut no_sanitize_span = None ;
8280
83- let fn_sig_outer = || {
84- use DefKind :: * ;
85-
86- let def_kind = tcx. def_kind ( did) ;
87- if let Fn | AssocFn | Variant | Ctor ( ..) = def_kind { Some ( tcx. fn_sig ( did) ) } else { None }
88- } ;
89-
9081 for attr in attrs. iter ( ) {
9182 // In some cases, attribute are only valid on functions, but it's the `check_attr`
9283 // pass that check that they aren't used anywhere else, rather this module.
9384 // In these cases, we bail from performing further checks that are only meaningful for
9485 // functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
9586 // report a delayed bug, just in case `check_attr` isn't doing its job.
9687 let fn_sig = || {
97- let sig = fn_sig_outer ( ) ;
98- if sig. is_none ( ) {
88+ use DefKind :: * ;
89+
90+ let def_kind = tcx. def_kind ( did) ;
91+ if let Fn | AssocFn | Variant | Ctor ( ..) = def_kind {
92+ Some ( tcx. fn_sig ( did) )
93+ } else {
9994 tcx. dcx ( )
10095 . span_delayed_bug ( attr. span , "this attribute can only be applied to functions" ) ;
96+ None
10197 }
102- sig
10398 } ;
10499
105100 let Some ( Ident { name, .. } ) = attr. ident ( ) else {
@@ -618,93 +613,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
618613 }
619614 }
620615
621- if let Some ( sig) = fn_sig_outer ( ) {
622- // Collect target features from types reachable from arguments.
623- // We define a type as "reachable" if:
624- // - it is a function argument
625- // - it is a field of a reachable struct
626- // - there is a reachable reference to it
627- // FIXME(struct_target_features): we may want to cache the result of this computation.
628- let mut visited_types = FxHashSet :: default ( ) ;
629- let mut reachable_types: Vec < _ > = sig. skip_binder ( ) . inputs ( ) . skip_binder ( ) . to_owned ( ) ;
630- let mut additional_tf = vec ! [ ] ;
631-
632- while let Some ( ty) = reachable_types. pop ( ) {
633- if visited_types. contains ( & ty) {
634- continue ;
635- }
636- visited_types. insert ( ty) ;
637- match ty. kind ( ) {
638- ty:: Alias ( ..) => {
639- if let Ok ( t) =
640- tcx. try_normalize_erasing_regions ( tcx. param_env ( did. to_def_id ( ) ) , ty)
641- {
642- reachable_types. push ( t)
643- }
644- }
645-
646- ty:: Ref ( _, inner, _) => reachable_types. push ( * inner) ,
647- ty:: Tuple ( tys) => reachable_types. extend ( tys. iter ( ) ) ,
648- ty:: Adt ( adt_def, args) => {
649- additional_tf. extend_from_slice ( tcx. struct_target_features ( adt_def. did ( ) ) ) ;
650- // This only recurses into structs as i.e. an Option<TargetFeature> is an ADT
651- // that doesn't actually always contain a TargetFeature.
652- if adt_def. is_struct ( ) {
653- reachable_types. extend (
654- adt_def
655- . variant ( VariantIdx :: from_usize ( 0 ) )
656- . fields
657- . iter ( )
658- . map ( |field| field. ty ( tcx, args) ) ,
659- ) ;
660- }
661- }
662- ty:: Bool
663- | ty:: Char
664- | ty:: Int ( ..)
665- | ty:: Uint ( ..)
666- | ty:: Float ( ..)
667- | ty:: Foreign ( ..)
668- | ty:: Str
669- | ty:: Array ( ..)
670- | ty:: Pat ( ..)
671- | ty:: Slice ( ..)
672- | ty:: RawPtr ( ..)
673- | ty:: FnDef ( ..)
674- | ty:: FnPtr ( ..)
675- | ty:: Dynamic ( ..)
676- | ty:: Closure ( ..)
677- | ty:: CoroutineClosure ( ..)
678- | ty:: Coroutine ( ..)
679- | ty:: CoroutineWitness ( ..)
680- | ty:: Never
681- | ty:: Param ( ..)
682- | ty:: Bound ( ..)
683- | ty:: Placeholder ( ..)
684- | ty:: Infer ( ..)
685- | ty:: Error ( ..) => ( ) ,
686- }
687- }
688-
689- // FIXME(struct_target_features): is this really necessary?
690- if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
691- tcx. dcx ( ) . span_err (
692- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
693- "cannot use a struct with target features in a function with non-Rust ABI" ,
694- ) ;
695- }
696- if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
697- tcx. dcx ( ) . span_err (
698- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
699- "cannot use a struct with target features in a #[inline(always)] function" ,
700- ) ;
701- }
702- codegen_fn_attrs
703- . target_features
704- . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
705- }
706-
707- // If a function uses non-default target_features it can't be inlined into general
616+ // If a function uses #[target_feature] it can't be inlined into general
708617 // purpose functions as they wouldn't have the right target features
709618 // enabled. For that reason we also forbid #[inline(always)] as it can't be
710619 // respected.
@@ -849,20 +758,6 @@ fn check_link_name_xor_ordinal(
849758 }
850759}
851760
852- fn struct_target_features ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> & [ TargetFeature ] {
853- let mut features = vec ! [ ] ;
854- let supported_features = tcx. supported_target_features ( LOCAL_CRATE ) ;
855- for attr in tcx. get_attrs ( def_id, sym:: target_feature) {
856- from_target_feature ( tcx, attr, supported_features, & mut features) ;
857- }
858- tcx. arena . alloc_slice ( & features)
859- }
860-
861761pub fn provide ( providers : & mut Providers ) {
862- * providers = Providers {
863- codegen_fn_attrs,
864- should_inherit_track_caller,
865- struct_target_features,
866- ..* providers
867- } ;
762+ * providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..* providers } ;
868763}
0 commit comments