@@ -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