@@ -6,6 +6,7 @@ use rustc_errors::Applicability;
66use rustc_hir:: def:: DefKind ;
77use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
88use rustc_middle:: bug;
9+ use rustc_middle:: middle:: codegen_fn_attrs:: TargetFeature ;
910use rustc_middle:: query:: Providers ;
1011use rustc_middle:: ty:: TyCtxt ;
1112use rustc_session:: parse:: feature_err;
@@ -18,7 +19,7 @@ pub fn from_target_feature(
1819 tcx : TyCtxt < ' _ > ,
1920 attr : & ast:: Attribute ,
2021 supported_target_features : & UnordMap < String , Option < Symbol > > ,
21- target_features : & mut Vec < Symbol > ,
22+ target_features : & mut Vec < TargetFeature > ,
2223) {
2324 let Some ( list) = attr. meta_item_list ( ) else { return } ;
2425 let bad_item = |span| {
@@ -99,14 +100,27 @@ pub fn from_target_feature(
99100 } ) ) ;
100101 }
101102
102- // Add both explicit and implied target features, using a set to deduplicate
103- let mut target_features_set = UnordSet :: new ( ) ;
103+ // Add explicit features
104+ target_features. extend (
105+ added_target_features. iter ( ) . copied ( ) . map ( |name| TargetFeature { name, implied : false } ) ,
106+ ) ;
107+
108+ // Add implied features
109+ let mut implied_target_features = UnordSet :: new ( ) ;
104110 for feature in added_target_features. iter ( ) {
105- target_features_set
111+ implied_target_features
106112 . extend_unord ( tcx. implied_target_features ( * feature) . clone ( ) . into_items ( ) ) ;
107113 }
108- target_features_set. extend ( added_target_features) ;
109- target_features. extend ( target_features_set. into_sorted_stable_ord ( ) )
114+ for feature in added_target_features. iter ( ) {
115+ implied_target_features. remove ( feature) ;
116+ }
117+ target_features. extend (
118+ implied_target_features
119+ . into_sorted_stable_ord ( )
120+ . iter ( )
121+ . copied ( )
122+ . map ( |name| TargetFeature { name, implied : true } ) ,
123+ )
110124}
111125
112126/// Computes the set of target features used in a function for the purposes of
@@ -115,7 +129,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
115129 let mut target_features = tcx. sess . unstable_target_features . clone ( ) ;
116130 if tcx. def_kind ( did) . has_codegen_attrs ( ) {
117131 let attrs = tcx. codegen_fn_attrs ( did) ;
118- target_features. extend ( & attrs. target_features ) ;
132+ target_features. extend ( attrs. target_features . iter ( ) . map ( |feature| feature . name ) ) ;
119133 match attrs. instruction_set {
120134 None => { }
121135 Some ( InstructionSetAttr :: ArmA32 ) => {
0 commit comments