Change cfg parsers to produce symbols instead of strings.

This commit is contained in:
Nicholas Nethercote 2023-10-30 14:01:33 +11:00
parent bfcff7933e
commit 8e4ac980fd
4 changed files with 16 additions and 54 deletions

View file

@ -24,6 +24,7 @@ use rustc_session::Session;
use rustc_session::{lint, EarlyErrorHandler}; use rustc_session::{lint, EarlyErrorHandler};
use rustc_span::source_map::{FileLoader, FileName}; use rustc_span::source_map::{FileLoader, FileName};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Symbol;
use std::path::PathBuf; use std::path::PathBuf;
use std::result; use std::result;
use std::sync::Arc; use std::sync::Arc;
@ -64,7 +65,7 @@ impl Compiler {
} }
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`. /// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg<String> { pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg<Symbol> {
cfgs.into_iter() cfgs.into_iter()
.map(|s| { .map(|s| {
let sess = ParseSess::with_silent_emitter(Some(format!( let sess = ParseSess::with_silent_emitter(Some(format!(
@ -94,10 +95,7 @@ pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg<S
} }
MetaItemKind::NameValue(..) | MetaItemKind::Word => { MetaItemKind::NameValue(..) | MetaItemKind::Word => {
let ident = meta_item.ident().expect("multi-segment cfg key"); let ident = meta_item.ident().expect("multi-segment cfg key");
return ( return (ident.name, meta_item.value_str());
ident.name.to_string(),
meta_item.value_str().map(|sym| sym.to_string()),
);
} }
} }
} }
@ -118,11 +116,11 @@ pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg<S
error!(r#"expected `key` or `key="value"`"#); error!(r#"expected `key` or `key="value"`"#);
} }
}) })
.collect::<Cfg<String>>() .collect::<Cfg<Symbol>>()
} }
/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`. /// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg<String> { pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg<Symbol> {
// If any --check-cfg is passed then exhaustive_values and exhaustive_names // If any --check-cfg is passed then exhaustive_values and exhaustive_names
// are enabled by default. // are enabled by default.
let exhaustive_names = !specs.is_empty(); let exhaustive_names = !specs.is_empty();
@ -179,10 +177,7 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
for arg in args { for arg in args {
if arg.is_word() && arg.ident().is_some() { if arg.is_word() && arg.ident().is_some() {
let ident = arg.ident().expect("multi-segment cfg key"); let ident = arg.ident().expect("multi-segment cfg key");
check_cfg check_cfg.expecteds.entry(ident.name).or_insert(ExpectedValues::Any);
.expecteds
.entry(ident.name.to_string())
.or_insert(ExpectedValues::Any);
} else { } else {
error!("`names()` arguments must be simple identifiers"); error!("`names()` arguments must be simple identifiers");
} }
@ -200,7 +195,7 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
let ident = name.ident().expect("multi-segment cfg key"); let ident = name.ident().expect("multi-segment cfg key");
let expected_values = check_cfg let expected_values = check_cfg
.expecteds .expecteds
.entry(ident.name.to_string()) .entry(ident.name)
.and_modify(|expected_values| match expected_values { .and_modify(|expected_values| match expected_values {
ExpectedValues::Some(_) => {} ExpectedValues::Some(_) => {}
ExpectedValues::Any => { ExpectedValues::Any => {
@ -217,7 +212,7 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
for val in values { for val in values {
if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) { if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) {
expected_values.insert(Some(s.to_string())); expected_values.insert(Some(*s));
} else { } else {
error!("`values()` arguments must be string literals"); error!("`values()` arguments must be string literals");
} }
@ -271,10 +266,8 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
values_specified = true; values_specified = true;
for arg in args { for arg in args {
if let Some(LitKind::Str(s, _)) = if let Some(LitKind::Str(s, _)) = arg.lit().map(|lit| &lit.kind) {
arg.lit().map(|lit| &lit.kind) values.insert(Some(*s));
{
values.insert(Some(s.to_string()));
} else if arg.has_name(sym::any) } else if arg.has_name(sym::any)
&& let Some(args) = arg.meta_item_list() && let Some(args) = arg.meta_item_list()
{ {
@ -322,7 +315,7 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
for name in names { for name in names {
check_cfg check_cfg
.expecteds .expecteds
.entry(name.to_string()) .entry(name.name)
.and_modify(|v| match v { .and_modify(|v| match v {
ExpectedValues::Some(v) if !values_any_specified => { ExpectedValues::Some(v) if !values_any_specified => {
v.extend(values.clone()) v.extend(values.clone())

View file

@ -26,8 +26,8 @@ use rustc_session::{build_session, getopts, Session};
use rustc_session::{CompilerIO, EarlyErrorHandler}; use rustc_session::{CompilerIO, EarlyErrorHandler};
use rustc_span::edition::{Edition, DEFAULT_EDITION}; use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::FileName;
use rustc_span::SourceFileHashAlgorithm; use rustc_span::SourceFileHashAlgorithm;
use rustc_span::{FileName, Symbol};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel}; use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel}; use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
@ -38,7 +38,7 @@ use std::sync::Arc;
fn mk_session( fn mk_session(
handler: &mut EarlyErrorHandler, handler: &mut EarlyErrorHandler,
matches: getopts::Matches, matches: getopts::Matches,
) -> (Session, Cfg<String>) { ) -> (Session, Cfg<Symbol>) {
let registry = registry::Registry::new(&[]); let registry = registry::Registry::new(&[]);
let sessopts = build_session_options(handler, &matches); let sessopts = build_session_options(handler, &matches);
let cfg = parse_cfg(handler, matches.opt_strs("cfg")); let cfg = parse_cfg(handler, matches.opt_strs("cfg"));

View file

@ -59,8 +59,8 @@ pub fn add_configuration(
pub fn create_session( pub fn create_session(
handler: &EarlyErrorHandler, handler: &EarlyErrorHandler,
sopts: config::Options, sopts: config::Options,
cfg: Cfg<String>, cfg: Cfg<Symbol>,
check_cfg: CheckCfg<String>, mut check_cfg: CheckCfg<Symbol>,
locale_resources: &'static [&'static str], locale_resources: &'static [&'static str],
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>, file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
io: CompilerIO, io: CompilerIO,
@ -123,7 +123,6 @@ pub fn create_session(
let mut cfg = config::build_configuration(&sess, cfg); let mut cfg = config::build_configuration(&sess, cfg);
add_configuration(&mut cfg, &mut sess, &*codegen_backend); add_configuration(&mut cfg, &mut sess, &*codegen_backend);
let mut check_cfg = check_cfg.intern();
check_cfg.fill_well_known(&sess.target); check_cfg.fill_well_known(&sess.target);
// These configs use symbols, rather than strings. // These configs use symbols, rather than strings.

View file

@ -1386,30 +1386,6 @@ impl<T> Default for CheckCfg<T> {
} }
} }
impl CheckCfg<String> {
pub fn intern(self) -> CheckCfg<Symbol> {
CheckCfg {
exhaustive_names: self.exhaustive_names,
exhaustive_values: self.exhaustive_values,
expecteds: self
.expecteds
.into_iter()
.map(|(name, values)| {
(
Symbol::intern(&name),
match values {
ExpectedValues::Some(values) => ExpectedValues::Some(
values.into_iter().map(|b| b.map(|b| Symbol::intern(&b))).collect(),
),
ExpectedValues::Any => ExpectedValues::Any,
},
)
})
.collect(),
}
}
}
pub enum ExpectedValues<T> { pub enum ExpectedValues<T> {
Some(FxHashSet<Option<T>>), Some(FxHashSet<Option<T>>),
Any, Any,
@ -1582,13 +1558,7 @@ impl CheckCfg<Symbol> {
} }
} }
pub fn build_configuration(sess: &Session, user_cfg: Cfg<String>) -> Cfg<Symbol> { pub fn build_configuration(sess: &Session, mut user_cfg: Cfg<Symbol>) -> Cfg<Symbol> {
// We can now intern these strings.
let mut user_cfg: Cfg<Symbol> = user_cfg
.into_iter()
.map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b))))
.collect();
// Combine the configuration requested by the session (command line) with // Combine the configuration requested by the session (command line) with
// some default and generated configuration items. // some default and generated configuration items.
let default_cfg = default_configuration(sess); let default_cfg = default_configuration(sess);