@@ -600,26 +600,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
600600 }
601601
602602 if let Some ( sig) = fn_sig_outer ( ) {
603+ let mut additional_tf = vec ! [ ] ;
603604 for ty in sig. skip_binder ( ) . inputs ( ) . skip_binder ( ) {
604- let additional_tf =
605- tcx. struct_reachable_target_features ( tcx. param_env ( did. to_def_id ( ) ) . and ( * ty) ) ;
606- // FIXME(struct_target_features): is this really necessary?
607- if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
608- tcx. dcx ( ) . span_err (
609- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
610- "cannot use a struct with target features in a function with non-Rust ABI" ,
611- ) ;
612- }
613- if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
614- tcx. dcx ( ) . span_err (
615- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
616- "cannot use a struct with target features in a #[inline(always)] function" ,
617- ) ;
618- }
619- codegen_fn_attrs
620- . target_features
621- . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
605+ extend_with_struct_target_features (
606+ tcx,
607+ tcx. param_env ( did. to_def_id ( ) ) . and ( * ty) ,
608+ & mut additional_tf,
609+ )
610+ }
611+ // FIXME(struct_target_features): is this really necessary?
612+ if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
613+ tcx. dcx ( ) . span_err (
614+ tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
615+ "cannot use a struct with target features in a function with non-Rust ABI" ,
616+ ) ;
622617 }
618+ if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
619+ tcx. dcx ( ) . span_err (
620+ tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
621+ "cannot use a struct with target features in a #[inline(always)] function" ,
622+ ) ;
623+ }
624+ codegen_fn_attrs
625+ . target_features
626+ . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
623627 }
624628
625629 // If a function uses non-default target_features it can't be inlined into general
@@ -814,38 +818,35 @@ fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeatur
814818 tcx. arena . alloc_slice ( & features)
815819}
816820
817- fn struct_reachable_target_features < ' tcx > (
821+ fn extend_with_struct_target_features < ' tcx > (
818822 tcx : TyCtxt < ' tcx > ,
819823 env : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
820- ) -> & ' tcx [ TargetFeature ] {
824+ target_features : & mut Vec < TargetFeature > ,
825+ ) {
821826 // Collect target features from types reachable from `env.value` by dereferencing a certain
822827 // number of references and resolving aliases.
823828
824829 let mut ty = env. value ;
825830 if matches ! ( ty. kind( ) , ty:: Alias ( ..) ) {
826831 ty = match tcx. try_normalize_erasing_regions ( env. param_env , ty) {
827832 Ok ( ty) => ty,
828- Err ( _) => return tcx . arena . alloc_slice ( & [ ] ) ,
833+ Err ( _) => return ,
829834 } ;
830835 }
831836 while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
832837 ty = * inner;
833838 }
834839
835- let tf = if let ty:: Adt ( adt_def, ..) = ty. kind ( ) {
836- tcx. struct_target_features ( adt_def. did ( ) )
837- } else {
838- & [ ]
839- } ;
840- tcx. arena . alloc_slice ( tf)
840+ if let ty:: Adt ( adt_def, ..) = ty. kind ( ) {
841+ target_features. extend_from_slice ( & tcx. struct_target_features ( adt_def. did ( ) ) ) ;
842+ }
841843}
842844
843845pub ( crate ) fn provide ( providers : & mut Providers ) {
844846 * providers = Providers {
845847 codegen_fn_attrs,
846848 should_inherit_track_caller,
847849 struct_target_features,
848- struct_reachable_target_features,
849850 ..* providers
850851 } ;
851852}
0 commit comments