@@ -308,7 +308,53 @@ pub fn check_tied_features(
308
308
/// Used to generate cfg variables and apply features
309
309
/// Must express features in the way Rust understands them
310
310
pub fn target_features ( sess : & Session , allow_unstable : bool ) -> Vec < Symbol > {
311
- let target_machine = create_informational_target_machine ( sess) ;
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
+
320
+ let mut features = FxHashSet :: default ( ) ;
321
+
322
+ // Add base features for the target
323
+ let target_machine = create_informational_target_machine ( sess, false ) ;
324
+ features. extend (
325
+ sess. target
326
+ . supported_target_features ( )
327
+ . iter ( )
328
+ . filter ( |( feature, _, _) | {
329
+ // skip checking special features, as LLVM may not understands them
330
+ if RUSTC_SPECIAL_FEATURES . contains ( feature) {
331
+ return true ;
332
+ }
333
+ // check that all features in a given smallvec are enabled
334
+ for llvm_feature in to_llvm_features ( sess, feature) {
335
+ let cstr = SmallCStr :: new ( llvm_feature) ;
336
+ if !unsafe { llvm:: LLVMRustHasFeature ( & target_machine, cstr. as_ptr ( ) ) } {
337
+ return false ;
338
+ }
339
+ }
340
+ true
341
+ } )
342
+ . map ( |( feature, _, _) | Symbol :: intern ( feature) ) ,
343
+ ) ;
344
+
345
+ // 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 == "+" {
351
+ features. extend ( sess. target . implied_target_features ( std:: iter:: once ( feature) ) ) ;
352
+ } else if add == "-" {
353
+ features. remove ( & feature) ;
354
+ }
355
+ }
356
+
357
+ // Filter enabled features based on feature gates
312
358
sess. target
313
359
. supported_target_features ( )
314
360
. iter ( )
@@ -320,18 +366,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
320
366
}
321
367
} )
322
368
. filter ( |feature| {
323
- // skip checking special features, as LLVM may not understands them
324
- if RUSTC_SPECIAL_FEATURES . contains ( feature) {
325
- return true ;
326
- }
327
- // check that all features in a given smallvec are enabled
328
- for llvm_feature in to_llvm_features ( sess, feature) {
329
- let cstr = SmallCStr :: new ( llvm_feature) ;
330
- if !unsafe { llvm:: LLVMRustHasFeature ( & target_machine, cstr. as_ptr ( ) ) } {
331
- return false ;
332
- }
333
- }
334
- true
369
+ RUSTC_SPECIAL_FEATURES . contains ( feature) || features. contains ( & Symbol :: intern ( feature) )
335
370
} )
336
371
. map ( |feature| Symbol :: intern ( feature) )
337
372
. collect ( )
@@ -440,7 +475,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
440
475
441
476
pub ( crate ) fn print ( req : & PrintRequest , mut out : & mut String , sess : & Session ) {
442
477
require_inited ( ) ;
443
- let tm = create_informational_target_machine ( sess) ;
478
+ let tm = create_informational_target_machine ( sess, true ) ;
444
479
match req. kind {
445
480
PrintKind :: TargetCPUs => {
446
481
// SAFETY generate a C compatible string from a byte slice to pass
0 commit comments