@@ -218,15 +218,17 @@ pub fn check_tied_features(
218218 sess : & Session ,
219219 features : & FxHashMap < & str , bool > ,
220220) -> Option < & ' static [ & ' static str ] > {
221- for tied in tied_target_features ( sess) {
222- // Tied features must be set to the same value, or not set at all
223- let mut tied_iter = tied. iter ( ) ;
224- let enabled = features. get ( tied_iter. next ( ) . unwrap ( ) ) ;
225- if tied_iter. any ( |f| enabled != features. get ( f) ) {
226- return Some ( tied) ;
221+ if !features. is_empty ( ) {
222+ for tied in tied_target_features ( sess) {
223+ // Tied features must be set to the same value, or not set at all
224+ let mut tied_iter = tied. iter ( ) ;
225+ let enabled = features. get ( tied_iter. next ( ) . unwrap ( ) ) ;
226+ if tied_iter. any ( |f| enabled != features. get ( f) ) {
227+ return Some ( tied) ;
228+ }
227229 }
228230 }
229- None
231+ return None ;
230232}
231233
232234// Used to generate cfg variables and apply features
@@ -440,6 +442,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
440442
441443 // -Ctarget-features
442444 let supported_features = supported_target_features ( sess) ;
445+ let mut featsmap = FxHashMap :: default ( ) ;
443446 let feats = sess
444447 . opts
445448 . cg
@@ -485,35 +488,36 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
485488 }
486489 diag. emit ( ) ;
487490 }
488- Some ( ( enable_disable, feature) )
491+
492+ if diagnostics {
493+ // FIXME(nagisa): figure out how to not allocate a full hashset here.
494+ featsmap. insert ( feature, enable_disable == '+' ) ;
495+ }
496+
497+ // rustc-specific features do not get passed down to LLVM…
498+ if RUSTC_SPECIFIC_FEATURES . contains ( & feature) {
499+ return None ;
500+ }
501+ // ... otherwise though we run through `to_llvm_features` when
502+ // passing requests down to LLVM. This means that all in-language
503+ // features also work on the command line instead of having two
504+ // different names when the LLVM name and the Rust name differ.
505+ Some (
506+ to_llvm_features ( sess, feature)
507+ . into_iter ( )
508+ . map ( move |f| format ! ( "{}{}" , enable_disable, f) ) ,
509+ )
489510 } )
490- . collect :: < SmallVec < [ ( char , & str ) ; 8 ] > > ( ) ;
491-
492- if diagnostics {
493- // FIXME(nagisa): figure out how to not allocate a full hashset here.
494- let featmap = feats. iter ( ) . map ( |& ( flag, feat) | ( feat, flag == '+' ) ) . collect ( ) ;
495- if let Some ( f) = check_tied_features ( sess, & featmap) {
496- sess. err ( & format ! (
497- "target features {} must all be enabled or disabled together" ,
498- f. join( ", " )
499- ) ) ;
500- }
511+ . flatten ( ) ;
512+ features. extend ( feats) ;
513+
514+ if diagnostics && let Some ( f) = check_tied_features ( sess, & featsmap) {
515+ sess. err ( & format ! (
516+ "target features {} must all be enabled or disabled together" ,
517+ f. join( ", " )
518+ ) ) ;
501519 }
502520
503- features. extend ( feats. into_iter ( ) . flat_map ( |( enable_disable, feature) | {
504- // rustc-specific features do not get passed down to LLVM…
505- if RUSTC_SPECIFIC_FEATURES . contains ( & feature) {
506- return SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
507- }
508- // ... otherwise though we run through `to_llvm_features` when
509- // passing requests down to LLVM. This means that all in-language
510- // features also work on the command line instead of having two
511- // different names when the LLVM name and the Rust name differ.
512- to_llvm_features ( sess, feature)
513- . into_iter ( )
514- . map ( |f| format ! ( "{}{}" , enable_disable, f) )
515- . collect ( )
516- } ) ) ;
517521 features
518522}
519523
0 commit comments