@@ -319,7 +319,6 @@ pub fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec<Symbol>
319319        sess. target 
320320            . rust_target_features ( ) 
321321            . iter ( ) 
322-             . filter ( |( _,  gate,  _) | gate. in_cfg ( ) ) 
323322            . filter ( |( feature,  _,  _) | { 
324323                // skip checking special features, as LLVM may not understand them 
325324                if  RUSTC_SPECIAL_FEATURES . contains ( feature)  { 
@@ -388,9 +387,13 @@ pub fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec<Symbol>
388387    sess. target 
389388        . rust_target_features ( ) 
390389        . iter ( ) 
391-         . filter ( |( _,  gate,  _) | gate. in_cfg ( ) ) 
392390        . filter_map ( |( feature,  gate,  _) | { 
393-             if  sess. is_nightly_build ( )  || allow_unstable || gate. requires_nightly ( ) . is_none ( )  { 
391+             // The `allow_unstable` set is used by rustc internally to determined which target 
392+             // features are truly available, so we want to return even perma-unstable "forbidden" 
393+             // features. 
394+             if  allow_unstable
395+                 || ( gate. in_cfg ( )  && ( sess. is_nightly_build ( )  || gate. requires_nightly ( ) . is_none ( ) ) ) 
396+             { 
394397                Some ( * feature) 
395398            }  else  { 
396399                None 
@@ -670,12 +673,6 @@ pub(crate) fn global_llvm_features(
670673        // Will only be filled when `diagnostics` is set! 
671674        let  mut  featsmap = FxHashMap :: default ( ) ; 
672675
673-         // Ensure that all ABI-required features are enabled, and the ABI-forbidden ones 
674-         // are disabled. 
675-         let  abi_feature_constraints = sess. target . abi_required_features ( ) ; 
676-         let  abi_incompatible_set =
677-             FxHashSet :: from_iter ( abi_feature_constraints. incompatible . iter ( ) . copied ( ) ) ; 
678- 
679676        // Compute implied features 
680677        let  mut  all_rust_features = vec ! [ ] ; 
681678        for  feature in  sess. opts . cg . target_feature . split ( ',' )  { 
@@ -746,52 +743,11 @@ pub(crate) fn global_llvm_features(
746743                    } 
747744                } 
748745
749-                 // Ensure that the features we enable/disable are compatible with the ABI. 
750-                 if  enable { 
751-                     if  abi_incompatible_set. contains ( feature)  { 
752-                         sess. dcx ( ) . emit_warn ( ForbiddenCTargetFeature  { 
753-                             feature, 
754-                             enabled :  "enabled" , 
755-                             reason :  "this feature is incompatible with the target ABI" , 
756-                         } ) ; 
757-                     } 
758-                 }  else  { 
759-                     // FIXME: we have to request implied features here since 
760-                     // negative features do not handle implied features above. 
761-                     for  & required in  abi_feature_constraints. required . iter ( )  { 
762-                         let  implied =
763-                             sess. target . implied_target_features ( std:: iter:: once ( required) ) ; 
764-                         if  implied. contains ( feature)  { 
765-                             sess. dcx ( ) . emit_warn ( ForbiddenCTargetFeature  { 
766-                                 feature, 
767-                                 enabled :  "disabled" , 
768-                                 reason :  "this feature is required by the target ABI" , 
769-                             } ) ; 
770-                         } 
771-                     } 
772-                 } 
773- 
774746                // FIXME(nagisa): figure out how to not allocate a full hashset here. 
775747                featsmap. insert ( feature,  enable) ; 
776748            } 
777749        } 
778750
779-         // To be sure the ABI-relevant features are all in the right state, we explicitly 
780-         // (un)set them here. This means if the target spec sets those features wrong, 
781-         // we will silently correct them rather than silently producing wrong code. 
782-         // (The target sanity check tries to catch this, but we can't know which features are 
783-         // enabled in LLVM by default so we can't be fully sure about that check.) 
784-         // We add these at the beginning of the list so that `-Ctarget-features` can 
785-         // still override it... that's unsound, but more compatible with past behavior. 
786-         all_rust_features. splice ( 
787-             0 ..0 , 
788-             abi_feature_constraints
789-                 . required 
790-                 . iter ( ) 
791-                 . map ( |& f| ( true ,  f) ) 
792-                 . chain ( abi_feature_constraints. incompatible . iter ( ) . map ( |& f| ( false ,  f) ) ) , 
793-         ) ; 
794- 
795751        // Translate this into LLVM features. 
796752        let  feats = all_rust_features
797753            . iter ( ) 
0 commit comments