@@ -603,26 +603,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
603
603
}
604
604
605
605
if let Some ( sig) = fn_sig_outer ( ) {
606
+ let mut additional_tf = vec ! [ ] ;
606
607
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
+ )
625
613
}
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 } ) ) ;
626
630
}
627
631
628
632
// 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
777
781
tcx. arena . alloc_slice ( & features)
778
782
}
779
783
780
- fn struct_reachable_target_features < ' tcx > (
784
+ fn extend_with_struct_target_features < ' tcx > (
781
785
tcx : TyCtxt < ' tcx > ,
782
786
env : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
783
- ) -> & ' tcx [ TargetFeature ] {
787
+ target_features : & mut Vec < TargetFeature > ,
788
+ ) {
784
789
// Collect target features from types reachable from `env.value` by dereferencing a certain
785
790
// number of references and resolving aliases.
786
791
787
792
let mut ty = env. value ;
788
793
if matches ! ( ty. kind( ) , ty:: Alias ( ..) ) {
789
794
ty = match tcx. try_normalize_erasing_regions ( env. param_env , ty) {
790
795
Ok ( ty) => ty,
791
- Err ( _) => return tcx . arena . alloc_slice ( & [ ] ) ,
796
+ Err ( _) => return ,
792
797
} ;
793
798
}
794
799
while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
795
800
ty = * inner;
796
801
}
797
802
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
+ }
804
806
}
805
807
806
808
pub ( crate ) fn provide ( providers : & mut Providers ) {
807
809
* providers = Providers {
808
810
codegen_fn_attrs,
809
811
should_inherit_track_caller,
810
812
struct_target_features,
811
- struct_reachable_target_features,
812
813
..* providers
813
814
} ;
814
815
}
0 commit comments