about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro.albini@ferrous-systems.com>2023-03-10 14:05:43 +0100
committerPietro Albini <pietro.albini@ferrous-systems.com>2023-04-03 09:30:29 +0200
commitbc991de2336df5e6c29d50fb448778c725f9d9cf (patch)
tree83c1b5a136abcecbeca8f354131d21a7be415cc4
parent9cb4373a8458e38c1ed8b1d8e768e11f305e551f (diff)
downloadrust-bc991de2336df5e6c29d50fb448778c725f9d9cf.tar.gz
rust-bc991de2336df5e6c29d50fb448778c725f9d9cf.zip
reduce allocations when validating cfgs
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header/cfg.rs64
2 files changed, 47 insertions, 20 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 3d3f8278f65..f03f732684c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -22,8 +22,9 @@ macro_rules! string_enum {
 
         impl $name {
             $vis const VARIANTS: &'static [Self] = &[$(Self::$variant,)*];
+            $vis const STR_VARIANTS: &'static [&'static str] = &[$(Self::$variant.to_str(),)*];
 
-            $vis fn to_str(&self) -> &'static str {
+            $vis const fn to_str(&self) -> &'static str {
                 match self {
                     $(Self::$variant => $repr,)*
                 }
diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs
index a6812792c27..a14943c9466 100644
--- a/src/tools/compiletest/src/header/cfg.rs
+++ b/src/tools/compiletest/src/header/cfg.rs
@@ -1,4 +1,4 @@
-use crate::common::{Config, CompareMode, Debugger};
+use crate::common::{CompareMode, Config, Debugger};
 use std::collections::HashSet;
 
 /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
@@ -48,7 +48,7 @@ pub(super) fn parse_cfg_name_directive<'a>(
                     outcome = MatchOutcome::NoMatch;
                 }
             }
-            $(else if $allowed_names.contains(name) {
+            $(else if $allowed_names.custom_contains(name) {
                 message = Some(format_message());
                 outcome = MatchOutcome::NoMatch;
             })?
@@ -69,13 +69,6 @@ pub(super) fn parse_cfg_name_directive<'a>(
             }
         };
     }
-    macro_rules! hashset {
-        ($($value:expr),* $(,)?) => {{
-            let mut set = HashSet::new();
-            $(set.insert($value);)*
-            set
-        }}
-    }
 
     let target_cfgs = config.target_cfgs();
     let target_cfg = config.target_cfg();
@@ -140,7 +133,7 @@ pub(super) fn parse_cfg_name_directive<'a>(
 
     condition! {
         name: &config.channel,
-        allowed_names: hashset!["stable", "beta", "nightly"],
+        allowed_names: &["stable", "beta", "nightly"],
         message: "when the release channel is {name}",
     }
     condition! {
@@ -155,7 +148,7 @@ pub(super) fn parse_cfg_name_directive<'a>(
     }
     condition! {
         name: config.stage_id.split('-').next().unwrap(),
-        allowed_names: hashset!["stable", "beta", "nightly"],
+        allowed_names: &["stable", "beta", "nightly"],
         message: "when the bootstrapping stage is {name}",
     }
     condition! {
@@ -170,20 +163,17 @@ pub(super) fn parse_cfg_name_directive<'a>(
     }
     maybe_condition! {
         name: config.debugger.as_ref().map(|d| d.to_str()),
-        allowed_names: Debugger::VARIANTS
-            .iter()
-            .map(|v| v.to_str())
-            .collect::<HashSet<_>>(),
+        allowed_names: &Debugger::STR_VARIANTS,
         message: "when the debugger is {name}",
     }
     maybe_condition! {
         name: config.compare_mode
             .as_ref()
             .map(|d| format!("compare-mode-{}", d.to_str())),
-        allowed_names: CompareMode::VARIANTS
-            .iter()
-            .map(|cm| format!("compare-mode-{}", cm.to_str()))
-            .collect::<HashSet<_>>(),
+        allowed_names: ContainsPrefixed {
+            prefix: "compare-mode-",
+            inner: CompareMode::STR_VARIANTS,
+        },
         message: "when comparing with {name}",
     }
 
@@ -231,3 +221,39 @@ pub(super) enum MatchOutcome {
     /// The directive is handled by other parts of our tooling.
     External,
 }
+
+trait CustomContains {
+    fn custom_contains(&self, item: &str) -> bool;
+}
+
+impl CustomContains for HashSet<String> {
+    fn custom_contains(&self, item: &str) -> bool {
+        self.contains(item)
+    }
+}
+
+impl CustomContains for &[&str] {
+    fn custom_contains(&self, item: &str) -> bool {
+        self.contains(&item)
+    }
+}
+
+impl<const N: usize> CustomContains for [&str; N] {
+    fn custom_contains(&self, item: &str) -> bool {
+        self.contains(&item)
+    }
+}
+
+struct ContainsPrefixed<T: CustomContains> {
+    prefix: &'static str,
+    inner: T,
+}
+
+impl<T: CustomContains> CustomContains for ContainsPrefixed<T> {
+    fn custom_contains(&self, item: &str) -> bool {
+        match item.strip_prefix(self.prefix) {
+            Some(stripped) => self.inner.custom_contains(stripped),
+            None => false,
+        }
+    }
+}