@@ -600,26 +600,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
600
600
}
601
601
602
602
if let Some ( sig) = fn_sig_outer ( ) {
603
+ let mut additional_tf = vec ! [ ] ;
603
604
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
+ ) ;
622
617
}
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 } ) ) ;
623
627
}
624
628
625
629
// 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
814
818
tcx. arena . alloc_slice ( & features)
815
819
}
816
820
817
- fn struct_reachable_target_features < ' tcx > (
821
+ fn extend_with_struct_target_features < ' tcx > (
818
822
tcx : TyCtxt < ' tcx > ,
819
823
env : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
820
- ) -> & ' tcx [ TargetFeature ] {
824
+ target_features : & mut Vec < TargetFeature > ,
825
+ ) {
821
826
// Collect target features from types reachable from `env.value` by dereferencing a certain
822
827
// number of references and resolving aliases.
823
828
824
829
let mut ty = env. value ;
825
830
if matches ! ( ty. kind( ) , ty:: Alias ( ..) ) {
826
831
ty = match tcx. try_normalize_erasing_regions ( env. param_env , ty) {
827
832
Ok ( ty) => ty,
828
- Err ( _) => return tcx . arena . alloc_slice ( & [ ] ) ,
833
+ Err ( _) => return ,
829
834
} ;
830
835
}
831
836
while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
832
837
ty = * inner;
833
838
}
834
839
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
+ }
841
843
}
842
844
843
845
pub ( crate ) fn provide ( providers : & mut Providers ) {
844
846
* providers = Providers {
845
847
codegen_fn_attrs,
846
848
should_inherit_track_caller,
847
849
struct_target_features,
848
- struct_reachable_target_features,
849
850
..* providers
850
851
} ;
851
852
}
0 commit comments