@@ -308,19 +308,10 @@ pub fn check_tied_features(
308308/// Used to generate cfg variables and apply features
309309/// Must express features in the way Rust understands them
310310pub fn target_features ( sess : & Session , allow_unstable : bool ) -> Vec < Symbol > {
311- let rust_features = sess
312- . target
313- . supported_target_features ( )
314- . iter ( )
315- . map ( |( feature, _, _) | {
316- ( to_llvm_features ( sess, feature) . llvm_feature_name , Symbol :: intern ( feature) )
317- } )
318- . collect :: < FxHashMap < _ , _ > > ( ) ;
319-
320311 let mut features = FxHashSet :: default ( ) ;
321312
322313 // Add base features for the target
323- let target_machine = create_informational_target_machine ( sess, false ) ;
314+ let target_machine = create_informational_target_machine ( sess, true ) ;
324315 features. extend (
325316 sess. target
326317 . supported_target_features ( )
@@ -343,13 +334,16 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
343334 ) ;
344335
345336 // Add enabled features
346- for llvm_feature in global_llvm_features ( sess, false ) {
347- let ( add, llvm_feature) = llvm_feature. split_at ( 1 ) ;
348- let feature =
349- rust_features. get ( llvm_feature) . cloned ( ) . unwrap_or ( Symbol :: intern ( llvm_feature) ) ;
350- if add == "+" {
337+ for ( enabled, feature) in
338+ sess. opts . cg . target_feature . split ( ',' ) . filter_map ( |s| match s. chars ( ) . next ( ) {
339+ Some ( '+' ) => Some ( ( true , Symbol :: intern ( & s[ 1 ..] ) ) ) ,
340+ Some ( '-' ) => Some ( ( false , Symbol :: intern ( & s[ 1 ..] ) ) ) ,
341+ _ => None ,
342+ } )
343+ {
344+ if enabled {
351345 features. extend ( sess. target . implied_target_features ( std:: iter:: once ( feature) ) ) ;
352- } else if add == "-" {
346+ } else {
353347 features. remove ( & feature) ;
354348 }
355349 }
@@ -475,7 +469,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
475469
476470pub ( crate ) fn print ( req : & PrintRequest , mut out : & mut String , sess : & Session ) {
477471 require_inited ( ) ;
478- let tm = create_informational_target_machine ( sess, true ) ;
472+ let tm = create_informational_target_machine ( sess, false ) ;
479473 match req. kind {
480474 PrintKind :: TargetCPUs => {
481475 // SAFETY generate a C compatible string from a byte slice to pass
@@ -523,7 +517,11 @@ pub fn target_cpu(sess: &Session) -> &str {
523517
524518/// The list of LLVM features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
525519/// `--target` and similar).
526- pub ( crate ) fn global_llvm_features ( sess : & Session , diagnostics : bool ) -> Vec < String > {
520+ pub ( crate ) fn global_llvm_features (
521+ sess : & Session ,
522+ diagnostics : bool ,
523+ only_base_features : bool ,
524+ ) -> Vec < String > {
527525 // Features that come earlier are overridden by conflicting features later in the string.
528526 // Typically we'll want more explicit settings to override the implicit ones, so:
529527 //
@@ -583,96 +581,109 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
583581 }
584582
585583 // -Ctarget-features
586- let supported_features = sess. target . supported_target_features ( ) ;
587- let ( llvm_major, _, _) = get_version ( ) ;
588- let mut featsmap = FxHashMap :: default ( ) ;
589- let feats = sess
590- . opts
591- . cg
592- . target_feature
593- . split ( ',' )
594- . filter_map ( |s| {
595- let enable_disable = match s. chars ( ) . next ( ) {
596- None => return None ,
597- Some ( c @ ( '+' | '-' ) ) => c,
598- Some ( _) => {
599- if diagnostics {
600- sess. dcx ( ) . emit_warn ( UnknownCTargetFeaturePrefix { feature : s } ) ;
584+ if !only_base_features {
585+ let supported_features = sess. target . supported_target_features ( ) ;
586+ let ( llvm_major, _, _) = get_version ( ) ;
587+ let mut featsmap = FxHashMap :: default ( ) ;
588+ let feats = sess
589+ . opts
590+ . cg
591+ . target_feature
592+ . split ( ',' )
593+ . filter_map ( |s| {
594+ let enable_disable = match s. chars ( ) . next ( ) {
595+ None => return None ,
596+ Some ( c @ ( '+' | '-' ) ) => c,
597+ Some ( _) => {
598+ if diagnostics {
599+ sess. dcx ( ) . emit_warn ( UnknownCTargetFeaturePrefix { feature : s } ) ;
600+ }
601+ return None ;
601602 }
602- return None ;
603- }
604- } ;
603+ } ;
605604
606- let feature = backend_feature_name ( sess, s) ?;
607- // Warn against use of LLVM specific feature names and unstable features on the CLI.
608- if diagnostics {
609- let feature_state = supported_features. iter ( ) . find ( |& & ( v, _, _) | v == feature) ;
610- if feature_state. is_none ( ) {
611- let rust_feature =
612- supported_features. iter ( ) . find_map ( |& ( rust_feature, _, _) | {
613- let llvm_features = to_llvm_features ( sess, rust_feature) ;
614- if llvm_features. contains ( feature)
615- && !llvm_features. contains ( rust_feature)
616- {
617- Some ( rust_feature)
618- } else {
619- None
605+ let feature = backend_feature_name ( sess, s) ?;
606+ // Warn against use of LLVM specific feature names and unstable features on the CLI.
607+ if diagnostics {
608+ let feature_state = supported_features. iter ( ) . find ( |& & ( v, _, _) | v == feature) ;
609+ if feature_state. is_none ( ) {
610+ let rust_feature =
611+ supported_features. iter ( ) . find_map ( |& ( rust_feature, _, _) | {
612+ let llvm_features = to_llvm_features ( sess, rust_feature) ;
613+ if llvm_features. contains ( feature)
614+ && !llvm_features. contains ( rust_feature)
615+ {
616+ Some ( rust_feature)
617+ } else {
618+ None
619+ }
620+ } ) ;
621+ let unknown_feature = if let Some ( rust_feature) = rust_feature {
622+ UnknownCTargetFeature {
623+ feature,
624+ rust_feature : PossibleFeature :: Some { rust_feature } ,
620625 }
621- } ) ;
622- let unknown_feature = if let Some ( rust_feature) = rust_feature {
623- UnknownCTargetFeature {
624- feature,
625- rust_feature : PossibleFeature :: Some { rust_feature } ,
626- }
627- } else {
628- UnknownCTargetFeature { feature, rust_feature : PossibleFeature :: None }
629- } ;
630- sess. dcx ( ) . emit_warn ( unknown_feature) ;
631- } else if feature_state
632- . is_some_and ( |( _name, feature_gate, _implied) | !feature_gate. is_stable ( ) )
633- {
634- // An unstable feature. Warn about using it.
635- sess. dcx ( ) . emit_warn ( UnstableCTargetFeature { feature } ) ;
626+ } else {
627+ UnknownCTargetFeature { feature, rust_feature : PossibleFeature :: None }
628+ } ;
629+ sess. dcx ( ) . emit_warn ( unknown_feature) ;
630+ } else if feature_state
631+ . is_some_and ( |( _name, feature_gate, _implied) | !feature_gate. is_stable ( ) )
632+ {
633+ // An unstable feature. Warn about using it.
634+ sess. dcx ( ) . emit_warn ( UnstableCTargetFeature { feature } ) ;
635+ }
636636 }
637- }
638637
639- if diagnostics {
640- // FIXME(nagisa): figure out how to not allocate a full hashset here.
641- featsmap. insert ( feature, enable_disable == '+' ) ;
642- }
638+ if diagnostics {
639+ // FIXME(nagisa): figure out how to not allocate a full hashset here.
640+ featsmap. insert ( feature, enable_disable == '+' ) ;
641+ }
643642
644- // rustc-specific features do not get passed down to LLVM…
645- if RUSTC_SPECIFIC_FEATURES . contains ( & feature) {
646- return None ;
647- }
643+ // rustc-specific features do not get passed down to LLVM…
644+ if RUSTC_SPECIFIC_FEATURES . contains ( & feature) {
645+ return None ;
646+ }
648647
649- // if the target-feature is "backchain" and LLVM version is greater than 18
650- // then we also need to add "+backchain" to the target-features attribute.
651- // otherwise, we will only add the naked `backchain` attribute to the attribute-group.
652- if feature == "backchain" && llvm_major < 18 {
653- return None ;
654- }
655- // ... otherwise though we run through `to_llvm_features` when
656- // passing requests down to LLVM. This means that all in-language
657- // features also work on the command line instead of having two
658- // different names when the LLVM name and the Rust name differ.
659- let llvm_feature = to_llvm_features ( sess, feature) ;
660-
661- Some (
662- std:: iter:: once ( format ! ( "{}{}" , enable_disable, llvm_feature. llvm_feature_name) )
663- . chain ( llvm_feature. dependency . into_iter ( ) . filter_map ( move |feat| {
664- match ( enable_disable, feat) {
648+ // if the target-feature is "backchain" and LLVM version is greater than 18
649+ // then we also need to add "+backchain" to the target-features attribute.
650+ // otherwise, we will only add the naked `backchain` attribute to the attribute-group.
651+ if feature == "backchain" && llvm_major < 18 {
652+ return None ;
653+ }
654+ // ... otherwise though we run through `to_llvm_features` when
655+ // passing requests down to LLVM. This means that all in-language
656+ // features also work on the command line instead of having two
657+ // different names when the LLVM name and the Rust name differ.
658+ let llvm_feature = to_llvm_features ( sess, feature) ;
659+
660+ Some (
661+ std:: iter:: once ( format ! (
662+ "{}{}" ,
663+ enable_disable, llvm_feature. llvm_feature_name
664+ ) )
665+ . chain ( llvm_feature. dependency . into_iter ( ) . filter_map (
666+ move |feat| match ( enable_disable, feat) {
665667 ( '-' | '+' , TargetFeatureFoldStrength :: Both ( f) )
666668 | ( '+' , TargetFeatureFoldStrength :: EnableOnly ( f) ) => {
667669 Some ( format ! ( "{enable_disable}{f}" ) )
668670 }
669671 _ => None ,
670- }
671- } ) ) ,
672- )
673- } )
674- . flatten ( ) ;
675- features. extend ( feats) ;
672+ } ,
673+ ) ) ,
674+ )
675+ } )
676+ . flatten ( ) ;
677+ features. extend ( feats) ;
678+
679+ if diagnostics && let Some ( f) = check_tied_features ( sess, & featsmap) {
680+ sess. dcx ( ) . emit_err ( TargetFeatureDisableOrEnable {
681+ features : f,
682+ span : None ,
683+ missing_features : None ,
684+ } ) ;
685+ }
686+ }
676687
677688 // -Zfixed-x18
678689 if sess. opts . unstable_opts . fixed_x18 {
@@ -683,14 +694,6 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
683694 }
684695 }
685696
686- if diagnostics && let Some ( f) = check_tied_features ( sess, & featsmap) {
687- sess. dcx ( ) . emit_err ( TargetFeatureDisableOrEnable {
688- features : f,
689- span : None ,
690- missing_features : None ,
691- } ) ;
692- }
693-
694697 features
695698}
696699
0 commit comments