@@ -617,26 +617,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
617
617
}
618
618
619
619
if let Some ( sig) = fn_sig_outer ( ) {
620
+ let mut additional_tf = vec ! [ ] ;
620
621
for ty in sig. skip_binder ( ) . inputs ( ) . skip_binder ( ) {
621
- let additional_tf =
622
- tcx. struct_reachable_target_features ( tcx. param_env ( did. to_def_id ( ) ) . and ( * ty) ) ;
623
- // FIXME(struct_target_features): is this really necessary?
624
- if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
625
- tcx. dcx ( ) . span_err (
626
- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
627
- "cannot use a struct with target features in a function with non-Rust ABI" ,
628
- ) ;
629
- }
630
- if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
631
- tcx. dcx ( ) . span_err (
632
- tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
633
- "cannot use a struct with target features in a #[inline(always)] function" ,
634
- ) ;
635
- }
636
- codegen_fn_attrs
637
- . target_features
638
- . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
622
+ extend_with_struct_target_features (
623
+ tcx,
624
+ tcx. param_env ( did. to_def_id ( ) ) . and ( * ty) ,
625
+ & mut additional_tf,
626
+ )
627
+ }
628
+ // FIXME(struct_target_features): is this really necessary?
629
+ if !additional_tf. is_empty ( ) && sig. skip_binder ( ) . abi ( ) != abi:: Abi :: Rust {
630
+ tcx. dcx ( ) . span_err (
631
+ tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
632
+ "cannot use a struct with target features in a function with non-Rust ABI" ,
633
+ ) ;
639
634
}
635
+ if !additional_tf. is_empty ( ) && codegen_fn_attrs. inline == InlineAttr :: Always {
636
+ tcx. dcx ( ) . span_err (
637
+ tcx. hir ( ) . span ( tcx. local_def_id_to_hir_id ( did) ) ,
638
+ "cannot use a struct with target features in a #[inline(always)] function" ,
639
+ ) ;
640
+ }
641
+ codegen_fn_attrs
642
+ . target_features
643
+ . extend ( additional_tf. iter ( ) . map ( |tf| TargetFeature { implied : true , ..* tf } ) ) ;
640
644
}
641
645
642
646
// If a function uses non-default target_features it can't be inlined into general
@@ -793,38 +797,35 @@ fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeatur
793
797
tcx. arena . alloc_slice ( & features)
794
798
}
795
799
796
- fn struct_reachable_target_features < ' tcx > (
800
+ fn extend_with_struct_target_features < ' tcx > (
797
801
tcx : TyCtxt < ' tcx > ,
798
802
env : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
799
- ) -> & ' tcx [ TargetFeature ] {
803
+ target_features : & mut Vec < TargetFeature > ,
804
+ ) {
800
805
// Collect target features from types reachable from `env.value` by dereferencing a certain
801
806
// number of references and resolving aliases.
802
807
803
808
let mut ty = env. value ;
804
809
if matches ! ( ty. kind( ) , ty:: Alias ( ..) ) {
805
810
ty = match tcx. try_normalize_erasing_regions ( env. param_env , ty) {
806
811
Ok ( ty) => ty,
807
- Err ( _) => return tcx . arena . alloc_slice ( & [ ] ) ,
812
+ Err ( _) => return ,
808
813
} ;
809
814
}
810
815
while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
811
816
ty = * inner;
812
817
}
813
818
814
- let tf = if let ty:: Adt ( adt_def, ..) = ty. kind ( ) {
815
- tcx. struct_target_features ( adt_def. did ( ) )
816
- } else {
817
- & [ ]
818
- } ;
819
- tcx. arena . alloc_slice ( tf)
819
+ if let ty:: Adt ( adt_def, ..) = ty. kind ( ) {
820
+ target_features. extend_from_slice ( & tcx. struct_target_features ( adt_def. did ( ) ) ) ;
821
+ }
820
822
}
821
823
822
824
pub fn provide ( providers : & mut Providers ) {
823
825
* providers = Providers {
824
826
codegen_fn_attrs,
825
827
should_inherit_track_caller,
826
828
struct_target_features,
827
- struct_reachable_target_features,
828
829
..* providers
829
830
} ;
830
831
}
0 commit comments