about summary refs log tree commit diff
path: root/compiler/rustc_session
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-03-04 22:58:34 +0100
committerGitHub <noreply@github.com>2022-03-04 22:58:34 +0100
commitafa85f08410aaa874f628c2704818ef2fb126f00 (patch)
treedc65aab68cf9b65f14011a7a7807a86dbc8cdf75 /compiler/rustc_session
parent9fcbc32053d5084d1de79bd484de82474cdae427 (diff)
parent4aa92aff054c8e89c61ac06551a405af828ade70 (diff)
downloadrust-afa85f08410aaa874f628c2704818ef2fb126f00.tar.gz
rust-afa85f08410aaa874f628c2704818ef2fb126f00.zip
Rollup merge of #94362 - Urgau:check-cfg-values, r=petrochenkov
Add well known values to `--check-cfg` implementation

This pull-request adds well known values for the well known names via `--check-cfg=values()`.

[RFC 3013: Checking conditional compilation at compile time](https://rust-lang.github.io/rfcs/3013-conditional-compilation-checking.html#checking-conditional-compilation-at-compile-time) doesn't define this at all, but this seems a nice improvement.
The activation is done by a empty `values()` (new syntax) similar to `names()` except that `names(foo)` also activate well known names while `values(aa, "aa", "kk")` would not.

As stated this use a different activation logic because well known values for the well known names are not always sufficient.
In fact this is problematic for every `target_*` cfg because of non builtin targets, as the current implementation use those built-ins targets to create the list the well known values.

The implementation is straight forward, first we gather (if necessary) all the values (lazily or not) and then we apply them.

r? ```@petrochenkov```
Diffstat (limited to 'compiler/rustc_session')
-rw-r--r--compiler/rustc_session/src/config.rs116
1 files changed, 110 insertions, 6 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d1cab628015..5f8aec80bcc 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -13,6 +13,7 @@ use rustc_data_structures::impl_stable_hash_via_hash;
 
 use rustc_target::abi::{Align, TargetDataLayout};
 use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings};
+use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS};
 
 use rustc_serialize::json;
 
@@ -1025,13 +1026,19 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig
 pub struct CheckCfg<T = String> {
     /// The set of all `names()`, if None no name checking is performed
     pub names_valid: Option<FxHashSet<T>>,
+    /// Is well known values activated
+    pub well_known_values: bool,
     /// The set of all `values()`
     pub values_valid: FxHashMap<T, FxHashSet<T>>,
 }
 
 impl<T> Default for CheckCfg<T> {
     fn default() -> Self {
-        CheckCfg { names_valid: Default::default(), values_valid: Default::default() }
+        CheckCfg {
+            names_valid: Default::default(),
+            values_valid: Default::default(),
+            well_known_values: false,
+        }
     }
 }
 
@@ -1047,6 +1054,7 @@ impl<T> CheckCfg<T> {
                 .iter()
                 .map(|(a, b)| (f(a), b.iter().map(|b| f(b)).collect()))
                 .collect(),
+            well_known_values: self.well_known_values,
         }
     }
 }
@@ -1060,8 +1068,9 @@ pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
 
 impl CrateCheckConfig {
     /// Fills a `CrateCheckConfig` with well-known configuration names.
-    pub fn fill_well_known(&mut self) {
-        // NOTE: This should be kept in sync with `default_configuration`
+    fn fill_well_known_names(&mut self) {
+        // NOTE: This should be kept in sync with `default_configuration` and
+        // `fill_well_known_values`
         const WELL_KNOWN_NAMES: &[Symbol] = &[
             sym::unix,
             sym::windows,
@@ -1086,11 +1095,106 @@ impl CrateCheckConfig {
             sym::doctest,
             sym::feature,
         ];
+
+        // We only insert well-known names if `names()` was activated
         if let Some(names_valid) = &mut self.names_valid {
-            for &name in WELL_KNOWN_NAMES {
-                names_valid.insert(name);
-            }
+            names_valid.extend(WELL_KNOWN_NAMES);
+        }
+    }
+
+    /// Fills a `CrateCheckConfig` with well-known configuration values.
+    fn fill_well_known_values(&mut self) {
+        if !self.well_known_values {
+            return;
         }
+
+        // NOTE: This should be kept in sync with `default_configuration` and
+        // `fill_well_known_names`
+
+        let panic_values = &PanicStrategy::all();
+
+        let atomic_values = &[
+            sym::ptr,
+            sym::integer(8usize),
+            sym::integer(16usize),
+            sym::integer(32usize),
+            sym::integer(64usize),
+            sym::integer(128usize),
+        ];
+
+        let sanitize_values = SanitizerSet::all()
+            .into_iter()
+            .map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap()));
+
+        // No-values
+        for name in [
+            sym::unix,
+            sym::windows,
+            sym::debug_assertions,
+            sym::proc_macro,
+            sym::test,
+            sym::doc,
+            sym::doctest,
+            sym::target_thread_local,
+        ] {
+            self.values_valid.entry(name).or_default();
+        }
+
+        // Pre-defined values
+        self.values_valid.entry(sym::panic).or_default().extend(panic_values);
+        self.values_valid.entry(sym::sanitize).or_default().extend(sanitize_values);
+        self.values_valid.entry(sym::target_has_atomic).or_default().extend(atomic_values);
+        self.values_valid
+            .entry(sym::target_has_atomic_load_store)
+            .or_default()
+            .extend(atomic_values);
+        self.values_valid
+            .entry(sym::target_has_atomic_equal_alignment)
+            .or_default()
+            .extend(atomic_values);
+
+        // Target specific values
+        for target in
+            TARGETS.iter().map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
+        {
+            self.values_valid
+                .entry(sym::target_os)
+                .or_default()
+                .insert(Symbol::intern(&target.options.os));
+            self.values_valid
+                .entry(sym::target_family)
+                .or_default()
+                .extend(target.options.families.iter().map(|family| Symbol::intern(family)));
+            self.values_valid
+                .entry(sym::target_arch)
+                .or_default()
+                .insert(Symbol::intern(&target.arch));
+            self.values_valid
+                .entry(sym::target_endian)
+                .or_default()
+                .insert(Symbol::intern(&target.options.endian.as_str()));
+            self.values_valid
+                .entry(sym::target_env)
+                .or_default()
+                .insert(Symbol::intern(&target.options.env));
+            self.values_valid
+                .entry(sym::target_abi)
+                .or_default()
+                .insert(Symbol::intern(&target.options.abi));
+            self.values_valid
+                .entry(sym::target_vendor)
+                .or_default()
+                .insert(Symbol::intern(&target.options.vendor));
+            self.values_valid
+                .entry(sym::target_pointer_width)
+                .or_default()
+                .insert(sym::integer(target.pointer_width));
+        }
+    }
+
+    pub fn fill_well_known(&mut self) {
+        self.fill_well_known_names();
+        self.fill_well_known_values();
     }
 
     /// Fills a `CrateCheckConfig` with configuration names and values that are actually active.