about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2024-08-06 00:35:32 -0400
committerCaleb Zulawski <caleb.zulawski@gmail.com>2024-08-07 00:45:00 -0400
commit8818c9552821721e4be5c19832b4e3ac64090feb (patch)
tree709edffd8770e88eb3762431b1c53649fc0e691d
parent0b98a0c72769c2549827ec2320beb5478ca3c335 (diff)
downloadrust-8818c9552821721e4be5c19832b4e3ac64090feb.tar.gz
rust-8818c9552821721e4be5c19832b4e3ac64090feb.zip
Disallow enabling features without their implied features
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs10
5 files changed, 11 insertions, 23 deletions
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 1a80824a3b7..9fd8ca43789 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -277,7 +277,7 @@ pub fn check_tied_features(
 /// Used to generate cfg variables and apply features
 /// Must express features in the way Rust understands them
 pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
-    let mut features = FxHashSet::default();
+    let mut features = vec![];
 
     // Add base features for the target
     let target_machine = create_informational_target_machine(sess, true);
@@ -313,7 +313,9 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
         if enabled {
             features.extend(sess.target.implied_target_features(std::iter::once(feature)));
         } else {
-            features.remove(&feature);
+            features.retain(|f| {
+                !sess.target.implied_target_features(std::iter::once(*f)).contains(&feature)
+            });
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 145b1ece230..cf8f7fa25d8 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -1,7 +1,7 @@
 use rustc_ast::ast;
 use rustc_attr::InstructionSetAttr;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
+use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::Applicability;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
@@ -108,8 +108,7 @@ pub fn from_target_feature(
     // Add implied features
     let mut implied_target_features = UnordSet::new();
     for feature in added_target_features.iter() {
-        implied_target_features
-            .extend_unord(tcx.implied_target_features(*feature).clone().into_items());
+        implied_target_features.extend(tcx.implied_target_features(*feature).clone());
     }
     for feature in added_target_features.iter() {
         implied_target_features.remove(feature);
@@ -179,7 +178,8 @@ pub(crate) fn provide(providers: &mut Providers) {
             }
         },
         implied_target_features: |tcx, feature| {
-            tcx.sess.target.implied_target_features(std::iter::once(feature)).into()
+            UnordSet::from(tcx.sess.target.implied_target_features(std::iter::once(feature)))
+                .into_sorted_stable_ord()
         },
         asm_target_features,
         ..*providers
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index e5c195f08d7..b5f3d07d90b 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -319,18 +319,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 .iter()
                 .any(|feature| !self.tcx.sess.target_features.contains(&feature.name))
         {
-            // Don't include implicit features in the error, unless only implicit features are
-            // missing. This should be rare, because it can only happen when an implicit feature
-            // is disabled, e.g. `+avx2,-avx`
-            let missing_explicit_features = attrs.target_features.iter().any(|feature| {
-                !feature.implied && !self.tcx.sess.target_features.contains(&feature.name)
-            });
             throw_ub_custom!(
                 fluent::const_eval_unavailable_target_features_for_fn,
                 unavailable_feats = attrs
                     .target_features
                     .iter()
-                    .filter(|&feature| !(missing_explicit_features && feature.implied)
+                    .filter(|&feature| !feature.implied
                         && !self.tcx.sess.target_features.contains(&feature.name))
                     .fold(String::new(), |mut s, feature| {
                         if !s.is_empty() {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b6a29432650..5b114c9515c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2183,7 +2183,7 @@ rustc_queries! {
         desc { "looking up supported target features" }
     }
 
-    query implied_target_features(feature: Symbol) -> &'tcx UnordSet<Symbol> {
+    query implied_target_features(feature: Symbol) -> &'tcx Vec<Symbol> {
         arena_cache
         eval_always
         desc { "looking up implied target features" }
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 0b4f0632f2b..54a4204da71 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -447,19 +447,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                             self.body_target_features.iter().any(|f| f.name == feature.name)
                         })
                     {
-                        // Don't include implicit features in the error, unless only implicit
-                        // features are missing.
-                        let missing_explicit_features = callee_features.iter().any(|feature| {
-                            !feature.implied
-                                && !self.body_target_features.iter().any(|body_feature| {
-                                    !feature.implied && body_feature.name == feature.name
-                                })
-                        });
                         let missing: Vec<_> = callee_features
                             .iter()
                             .copied()
                             .filter(|feature| {
-                                !(missing_explicit_features && feature.implied)
+                                !feature.implied
                                     && !self
                                         .body_target_features
                                         .iter()