@@ -617,26 +617,30 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
617617 }
618618
619619 if let Some ( sig) = fn_sig_outer ( ) {
620+ let mut additional_tf = vec ! [ ] ;
620621 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+ ) ;
639634 }
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 } ) ) ;
640644 }
641645
642646 // 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
793797 tcx. arena . alloc_slice ( & features)
794798}
795799
796- fn struct_reachable_target_features < ' tcx > (
800+ fn extend_with_struct_target_features < ' tcx > (
797801 tcx : TyCtxt < ' tcx > ,
798802 env : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
799- ) -> & ' tcx [ TargetFeature ] {
803+ target_features : & mut Vec < TargetFeature > ,
804+ ) {
800805 // Collect target features from types reachable from `env.value` by dereferencing a certain
801806 // number of references and resolving aliases.
802807
803808 let mut ty = env. value ;
804809 if matches ! ( ty. kind( ) , ty:: Alias ( ..) ) {
805810 ty = match tcx. try_normalize_erasing_regions ( env. param_env , ty) {
806811 Ok ( ty) => ty,
807- Err ( _) => return tcx . arena . alloc_slice ( & [ ] ) ,
812+ Err ( _) => return ,
808813 } ;
809814 }
810815 while let ty:: Ref ( _, inner, _) = ty. kind ( ) {
811816 ty = * inner;
812817 }
813818
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+ }
820822}
821823
822824pub fn provide ( providers : & mut Providers ) {
823825 * providers = Providers {
824826 codegen_fn_attrs,
825827 should_inherit_track_caller,
826828 struct_target_features,
827- struct_reachable_target_features,
828829 ..* providers
829830 } ;
830831}
0 commit comments