diff options
| author | Loïc BRANSTETT <lolo.branstett@numericable.fr> | 2022-02-19 23:06:11 +0100 |
|---|---|---|
| committer | Loïc BRANSTETT <lolo.branstett@numericable.fr> | 2022-02-22 22:41:49 +0100 |
| commit | da896d35f471a27eb7b9385d6eadf50a5f761265 (patch) | |
| tree | 4ccc8f3571c097b8c232031bbcebe61b81454d0c /compiler | |
| parent | cb4ee81ef555126e49b3e9f16ca6f12a3264a451 (diff) | |
| download | rust-da896d35f471a27eb7b9385d6eadf50a5f761265.tar.gz rust-da896d35f471a27eb7b9385d6eadf50a5f761265.zip | |
Improve CheckCfg internal representation
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_attr/src/builtin.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/interface.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 48 |
3 files changed, 58 insertions, 43 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 49043e9f5f9..cd2e150a190 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -463,27 +463,30 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat MetaItemKind::NameValue(..) | MetaItemKind::Word => { let name = cfg.ident().expect("multi-segment cfg predicate").name; let value = cfg.value_str(); - if sess.check_config.names_checked && !sess.check_config.names_valid.contains(&name) - { - sess.buffer_lint( - UNEXPECTED_CFGS, - cfg.span, - CRATE_NODE_ID, - "unexpected `cfg` condition name", - ); - } - if let Some(val) = value { - if sess.check_config.values_checked.contains(&name) - && !sess.check_config.values_valid.contains(&(name, val)) - { + if let Some(names_valid) = &sess.check_config.names_valid { + if !names_valid.contains(&name) { sess.buffer_lint( UNEXPECTED_CFGS, cfg.span, CRATE_NODE_ID, - "unexpected `cfg` condition value", + "unexpected `cfg` condition name", ); } } + if let Some(val) = value { + if let Some(values_valid) = &sess.check_config.values_valid { + if let Some(values) = values_valid.get(&name) { + if !values.contains(&val) { + sess.buffer_lint( + UNEXPECTED_CFGS, + cfg.span, + CRATE_NODE_ID, + "unexpected `cfg` condition value", + ); + } + } + } + } sess.config.contains(&(name, value)) } } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 609fc4b78c0..5e0d59bf1b1 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -169,11 +169,12 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { Ok(meta_item) if parser.token == token::Eof => { if let Some(args) = meta_item.meta_item_list() { if meta_item.has_name(sym::names) { - cfg.names_checked = true; + let names_valid = + cfg.names_valid.get_or_insert_with(|| FxHashSet::default()); for arg in args { if arg.is_word() && arg.ident().is_some() { let ident = arg.ident().expect("multi-segment cfg key"); - cfg.names_valid.insert(ident.name.to_string()); + names_valid.insert(ident.name.to_string()); } else { error!("`names()` arguments must be simple identifers"); } @@ -182,14 +183,19 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { } else if meta_item.has_name(sym::values) { if let Some((name, values)) = args.split_first() { if name.is_word() && name.ident().is_some() { + let values_valid = cfg + .values_valid + .get_or_insert_with(|| FxHashMap::default()); let ident = name.ident().expect("multi-segment cfg key"); - cfg.values_checked.insert(ident.to_string()); + let ident_values = values_valid + .entry(ident.to_string()) + .or_insert_with(|| FxHashSet::default()); + for val in values { if let Some(LitKind::Str(s, _)) = val.literal().map(|lit| &lit.kind) { - cfg.values_valid - .insert((ident.to_string(), s.to_string())); + ident_values.insert(s.to_string()); } else { error!( "`values()` arguments must be string literals" @@ -219,7 +225,11 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { ); } - cfg.names_valid.extend(cfg.values_checked.iter().cloned()); + if let Some(values_valid) = &cfg.values_valid { + if let Some(names_valid) = &mut cfg.names_valid { + names_valid.extend(values_valid.keys().cloned()); + } + } cfg }) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7a0d9a212c9..e0a3cc78b17 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -8,7 +8,7 @@ use crate::search_paths::SearchPath; use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; use crate::{early_error, early_warn, Session}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::impl_stable_hash_via_hash; use rustc_target::abi::{Align, TargetDataLayout}; @@ -1023,34 +1023,28 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig /// The parsed `--check-cfg` options pub struct CheckCfg<T = String> { - /// Set if `names()` checking is enabled - pub names_checked: bool, - /// The union of all `names()` - pub names_valid: FxHashSet<T>, - /// The set of names for which `values()` was used - pub values_checked: FxHashSet<T>, - /// The set of all (name, value) pairs passed in `values()` - pub values_valid: FxHashSet<(T, T)>, + /// The set of all `names()`, if none no names checking is performed + pub names_valid: Option<FxHashSet<T>>, + /// The set of all `values()`, if none no values chcking is performed + pub values_valid: Option<FxHashMap<T, FxHashSet<T>>>, } impl<T> Default for CheckCfg<T> { fn default() -> Self { - CheckCfg { - names_checked: false, - names_valid: FxHashSet::default(), - values_checked: FxHashSet::default(), - values_valid: FxHashSet::default(), - } + CheckCfg { names_valid: Default::default(), values_valid: Default::default() } } } impl<T> CheckCfg<T> { fn map_data<O: Eq + Hash>(&self, f: impl Fn(&T) -> O) -> CheckCfg<O> { CheckCfg { - names_checked: self.names_checked, - names_valid: self.names_valid.iter().map(|a| f(a)).collect(), - values_checked: self.values_checked.iter().map(|a| f(a)).collect(), - values_valid: self.values_valid.iter().map(|(a, b)| (f(a), f(b))).collect(), + names_valid: self + .names_valid + .as_ref() + .map(|names_valid| names_valid.iter().map(|a| f(a)).collect()), + values_valid: self.values_valid.as_ref().map(|values_valid| { + values_valid.iter().map(|(a, b)| (f(a), b.iter().map(|b| f(b)).collect())).collect() + }), } } } @@ -1090,17 +1084,25 @@ impl CrateCheckConfig { sym::doctest, sym::feature, ]; - for &name in WELL_KNOWN_NAMES { - self.names_valid.insert(name); + if let Some(names_valid) = &mut self.names_valid { + for &name in WELL_KNOWN_NAMES { + names_valid.insert(name); + } } } /// Fills a `CrateCheckConfig` with configuration names and values that are actually active. pub fn fill_actual(&mut self, cfg: &CrateConfig) { for &(k, v) in cfg { - self.names_valid.insert(k); + if let Some(names_valid) = &mut self.names_valid { + names_valid.insert(k); + } if let Some(v) = v { - self.values_valid.insert((k, v)); + if let Some(values_valid) = &mut self.values_valid { + values_valid.entry(k).and_modify(|values| { + values.insert(v); + }); + } } } } |
