@@ -603,26 +603,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
603603 }
604604
605605 if let Some ( sig) = fn_sig_outer ( ) {
606+ let mut additional_tf = vec ! [ ] ;
606607 for ty in sig. skip_binder ( ) . inputs ( ) . skip_binder ( ) {
607- let additional_tf =
608- tcx. struct_reachable_target_features ( tcx. param_env ( did. to_def_id ( ) ) . and ( * ty) ) ;
609- // FIXME(struct_target_features): is this really necessary?
610- if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
611- tcx. dcx ( ) . span_err (
612- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
613- "cannot use a struct with target features in a function with non-Rust ABI" ,
614- ) ;
615- }
616- if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
617- tcx. dcx ( ) . span_err (
618- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
619- "cannot use a struct with target features in a #[inline(always)] function" ,
620- ) ;
621- }
622- codegen_fn_attrs
623- . target_features
624- . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
608+ extend_with_struct_target_features (
609+ tcx,
610+ tcx. param_env ( did. to_def_id ( ) ) . and ( * ty) ,
611+ & mut additional_tf,
612+ )
625613 }
614+ // FIXME(struct_target_features): is this really necessary?
615+ if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
616+ tcx. dcx ( ) . span_err (
617+ tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
618+ "cannot use a struct with target features in a function with non-Rust ABI" ,
619+ ) ;
620+ }
621+ if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
622+ tcx. dcx ( ) . span_err (
623+ tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
624+ "cannot use a struct with target features in a #[inline(always)] function" ,
625+ ) ;
626+ }
627+ codegen_fn_attrs
628+ . target_features
629+ . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
626630 }
627631
628632 // If a function uses non-default target_features it can't be inlined into general
@@ -777,38 +781,35 @@ fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeatur
777781 tcx. arena . alloc_slice ( & features)
778782}
779783
780- fn struct_reachable_target_features < ' tcx > (
784+ fn extend_with_struct_target_features < ' tcx > (
781785 tcx : TyCtxt < ' tcx > ,
782786 env : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
783- ) -> & ' tcx [ TargetFeature ] {
787+ target_features : & mut Vec < TargetFeature > ,
788+ ) {
784789 // Collect target features from types reachable from `env.value` by dereferencing a certain
785790 // number of references and resolving aliases.
786791
787792 let mut ty = env. value ;
788793 if matches ! ( ty. kind( ) , ty:: Alias ( ..) ) {
789794 ty = match tcx. try_normalize_erasing_regions ( env. param_env , ty) {
790795 Ok ( ty) => ty,
791- Err ( _) => return tcx . arena . alloc_slice ( & [ ] ) ,
796+ Err ( _) => return ,
792797 } ;
793798 }
794799 while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
795800 ty = * inner;
796801 }
797802
798- let tf = if let ty:: Adt ( adt_def, ..) = ty. kind ( ) {
799- tcx. struct_target_features ( adt_def. did ( ) )
800- } else {
801- & [ ]
802- } ;
803- tcx. arena . alloc_slice ( tf)
803+ if let ty:: Adt ( adt_def, ..) = ty. kind ( ) {
804+ target_features. extend_from_slice ( & tcx. struct_target_features ( adt_def. did ( ) ) ) ;
805+ }
804806}
805807
806808pub ( crate ) fn provide ( providers : & mut Providers ) {
807809 * providers = Providers {
808810 codegen_fn_attrs,
809811 should_inherit_track_caller,
810812 struct_target_features,
811- struct_reachable_target_features,
812813 ..* providers
813814 } ;
814815}
0 commit comments