Skip to content

Commit 48a3865

Browse files
Rollup merge of #117268 - nnethercote:rustc_interface, r=oli-obk
`rustc_interface` cleanups Particularly in and around `--cfg` and `--check-cfg` handling. r? `@oli-obk`
2 parents 1db8c9d + 5438004 commit 48a3865

File tree

11 files changed

+76
-87
lines changed

11 files changed

+76
-87
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -4054,7 +4054,6 @@ dependencies = [
40544054
"rustc_hir_analysis",
40554055
"rustc_hir_typeck",
40564056
"rustc_incremental",
4057-
"rustc_index",
40584057
"rustc_lint",
40594058
"rustc_macros",
40604059
"rustc_metadata",

compiler/rustc_driver_impl/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ fn run_compiler(
317317
return Ok(());
318318
}
319319

320-
let cfg = interface::parse_cfgspecs(&early_error_handler, matches.opt_strs("cfg"));
320+
let cfg = interface::parse_cfg(&early_error_handler, matches.opt_strs("cfg"));
321321
let check_cfg = interface::parse_check_cfg(&early_error_handler, matches.opt_strs("check-cfg"));
322322
let (odir, ofile) = make_output(&matches);
323323
let mut config = interface::Config {

compiler/rustc_interface/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ rustc_middle = { path = "../rustc_middle" }
2626
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
2727
rustc_ast_passes = { path = "../rustc_ast_passes" }
2828
rustc_incremental = { path = "../rustc_incremental" }
29-
rustc_index = { path = "../rustc_index" }
3029
rustc_traits = { path = "../rustc_traits" }
3130
rustc_data_structures = { path = "../rustc_data_structures" }
3231
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }

compiler/rustc_interface/src/callbacks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
2626
})
2727
}
2828

29-
/// This is a callback from `rustc_ast` as it cannot access the implicit state
29+
/// This is a callback from `rustc_errors` as it cannot access the implicit state
3030
/// in `rustc_middle` otherwise. It is used when diagnostic messages are
3131
/// emitted and stores them in the current query, if there is one.
3232
fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {

compiler/rustc_interface/src/interface.rs

+20-15
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ use rustc_middle::{bug, ty};
1515
use rustc_parse::maybe_new_parser_from_source_str;
1616
use rustc_query_impl::QueryCtxt;
1717
use rustc_query_system::query::print_query_stack;
18-
use rustc_session::config::{self, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames};
19-
use rustc_session::parse::{CrateConfig, ParseSess};
18+
use rustc_session::config::{
19+
self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames,
20+
};
21+
use rustc_session::parse::ParseSess;
2022
use rustc_session::CompilerIO;
2123
use rustc_session::Session;
2224
use rustc_session::{lint, EarlyErrorHandler};
@@ -61,14 +63,13 @@ impl Compiler {
6163
}
6264
}
6365

64-
/// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
65-
pub fn parse_cfgspecs(
66-
handler: &EarlyErrorHandler,
67-
cfgspecs: Vec<String>,
68-
) -> FxHashSet<(String, Option<String>)> {
66+
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
67+
pub fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg<String> {
68+
// This creates a short-lived `SessionGlobals`, containing an interner. The
69+
// parsed values are converted from symbols to strings before exiting
70+
// because the symbols are meaningless once the interner is gone.
6971
rustc_span::create_default_session_if_not_set_then(move |_| {
70-
let cfg = cfgspecs
71-
.into_iter()
72+
cfgs.into_iter()
7273
.map(|s| {
7374
let sess = ParseSess::with_silent_emitter(Some(format!(
7475
"this error occurred on the command line: `--cfg={s}`"
@@ -97,7 +98,10 @@ pub fn parse_cfgspecs(
9798
}
9899
MetaItemKind::NameValue(..) | MetaItemKind::Word => {
99100
let ident = meta_item.ident().expect("multi-segment cfg key");
100-
return (ident.name, meta_item.value_str());
101+
return (
102+
ident.name.to_string(),
103+
meta_item.value_str().map(|sym| sym.to_string()),
104+
);
101105
}
102106
}
103107
}
@@ -118,13 +122,14 @@ pub fn parse_cfgspecs(
118122
error!(r#"expected `key` or `key="value"`"#);
119123
}
120124
})
121-
.collect::<CrateConfig>();
122-
cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect()
125+
.collect::<Cfg<String>>()
123126
})
124127
}
125128

126129
/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
127-
pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg {
130+
pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg<String> {
131+
// The comment about `SessionGlobals` and symbols in `parse_cfg` above
132+
// applies here too.
128133
rustc_span::create_default_session_if_not_set_then(move |_| {
129134
// If any --check-cfg is passed then exhaustive_values and exhaustive_names
130135
// are enabled by default.
@@ -357,8 +362,8 @@ pub struct Config {
357362
pub opts: config::Options,
358363

359364
/// cfg! configuration in addition to the default ones
360-
pub crate_cfg: FxHashSet<(String, Option<String>)>,
361-
pub crate_check_cfg: CheckCfg,
365+
pub crate_cfg: Cfg<String>,
366+
pub crate_check_cfg: CheckCfg<String>,
362367

363368
pub input: Input,
364369
pub output_dir: Option<PathBuf>,

compiler/rustc_interface/src/tests.rs

+10-19
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
#![allow(rustc::bad_opt_access)]
2-
use crate::interface::parse_cfgspecs;
3-
4-
use rustc_data_structures::fx::FxHashSet;
2+
use crate::interface::parse_cfg;
53
use rustc_data_structures::profiling::TimePassesFormat;
64
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
75
use rustc_session::config::rustc_optgroups;
6+
use rustc_session::config::Cfg;
87
use rustc_session::config::DebugInfo;
98
use rustc_session::config::Input;
109
use rustc_session::config::InstrumentXRay;
1110
use rustc_session::config::LinkSelfContained;
1211
use rustc_session::config::Polonius;
1312
use rustc_session::config::TraitSolver;
14-
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
13+
use rustc_session::config::{build_configuration, build_session_options};
1514
use rustc_session::config::{
1615
BranchProtection, Externs, OomStrategy, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
1716
ProcMacroExecutionStrategy, SymbolManglingVersion, WasiExecModel,
@@ -31,26 +30,18 @@ use rustc_span::FileName;
3130
use rustc_span::SourceFileHashAlgorithm;
3231
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
3332
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
34-
3533
use std::collections::{BTreeMap, BTreeSet};
3634
use std::num::NonZeroUsize;
3735
use std::path::{Path, PathBuf};
3836
use std::sync::Arc;
3937

40-
type CfgSpecs = FxHashSet<(String, Option<String>)>;
41-
42-
fn build_session_options_and_crate_config(
38+
fn mk_session(
4339
handler: &mut EarlyErrorHandler,
4440
matches: getopts::Matches,
45-
) -> (Options, CfgSpecs) {
46-
let sessopts = build_session_options(handler, &matches);
47-
let cfg = parse_cfgspecs(handler, matches.opt_strs("cfg"));
48-
(sessopts, cfg)
49-
}
50-
51-
fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, CfgSpecs) {
41+
) -> (Session, Cfg<String>) {
5242
let registry = registry::Registry::new(&[]);
53-
let (sessopts, cfg) = build_session_options_and_crate_config(handler, matches);
43+
let sessopts = build_session_options(handler, &matches);
44+
let cfg = parse_cfg(handler, matches.opt_strs("cfg"));
5445
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
5546
let io = CompilerIO {
5647
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
@@ -141,7 +132,7 @@ fn test_switch_implies_cfg_test() {
141132
let matches = optgroups().parse(&["--test".to_string()]).unwrap();
142133
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
143134
let (sess, cfg) = mk_session(&mut handler, matches);
144-
let cfg = build_configuration(&sess, to_crate_config(cfg));
135+
let cfg = build_configuration(&sess, cfg);
145136
assert!(cfg.contains(&(sym::test, None)));
146137
});
147138
}
@@ -153,7 +144,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
153144
let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
154145
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
155146
let (sess, cfg) = mk_session(&mut handler, matches);
156-
let cfg = build_configuration(&sess, to_crate_config(cfg));
147+
let cfg = build_configuration(&sess, cfg);
157148
let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
158149
assert!(test_items.next().is_some());
159150
assert!(test_items.next().is_none());
@@ -879,6 +870,6 @@ fn test_edition_parsing() {
879870
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
880871

881872
let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
882-
let (sessopts, _) = build_session_options_and_crate_config(&mut handler, matches);
873+
let sessopts = build_session_options(&mut handler, &matches);
883874
assert!(sessopts.edition == Edition::Edition2018)
884875
}

compiler/rustc_interface/src/util.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ use info;
33
use libloading::Library;
44
use rustc_ast as ast;
55
use rustc_codegen_ssa::traits::CodegenBackend;
6-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6+
use rustc_data_structures::fx::FxHashMap;
77
#[cfg(parallel_compiler)]
88
use rustc_data_structures::sync;
99
use rustc_errors::registry::Registry;
1010
use rustc_parse::validate_attr;
1111
use rustc_session as session;
12-
use rustc_session::config::CheckCfg;
13-
use rustc_session::config::{self, CrateType};
14-
use rustc_session::config::{OutFileName, OutputFilenames, OutputTypes};
12+
use rustc_session::config::{
13+
self, Cfg, CheckCfg, CrateType, OutFileName, OutputFilenames, OutputTypes,
14+
};
1515
use rustc_session::filesearch::sysroot_candidates;
1616
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
17-
use rustc_session::parse::CrateConfig;
1817
use rustc_session::{filesearch, output, Session};
1918
use rustc_span::edit_distance::find_best_match_for_name;
2019
use rustc_span::edition::Edition;
@@ -38,7 +37,7 @@ pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
3837
/// This is performed by checking whether a set of permitted features
3938
/// is available on the target machine, by querying the codegen backend.
4039
pub fn add_configuration(
41-
cfg: &mut CrateConfig,
40+
cfg: &mut Cfg<Symbol>,
4241
sess: &mut Session,
4342
codegen_backend: &dyn CodegenBackend,
4443
) {
@@ -60,8 +59,8 @@ pub fn add_configuration(
6059
pub fn create_session(
6160
handler: &EarlyErrorHandler,
6261
sopts: config::Options,
63-
cfg: FxHashSet<(String, Option<String>)>,
64-
check_cfg: CheckCfg,
62+
cfg: Cfg<String>,
63+
check_cfg: CheckCfg<String>,
6564
locale_resources: &'static [&'static str],
6665
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
6766
io: CompilerIO,
@@ -121,12 +120,13 @@ pub fn create_session(
121120

122121
codegen_backend.init(&sess);
123122

124-
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
123+
let mut cfg = config::build_configuration(&sess, cfg);
125124
add_configuration(&mut cfg, &mut sess, &*codegen_backend);
126125

127-
let mut check_cfg = config::to_crate_check_config(check_cfg);
126+
let mut check_cfg = check_cfg.intern();
128127
check_cfg.fill_well_known(&sess.target);
129128

129+
// These configs use symbols, rather than strings.
130130
sess.parse_sess.config = cfg;
131131
sess.parse_sess.check_config = check_cfg;
132132

compiler/rustc_session/src/config.rs

+26-26
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
99
use crate::{lint, HashStableContext};
1010
use crate::{EarlyErrorHandler, Session};
1111

12-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
12+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
1313
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
1414
use rustc_target::abi::Align;
1515
use rustc_target::spec::LinkSelfContainedComponents;
1616
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
1717
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
1818

19-
use crate::parse::{CrateCheckConfig, CrateConfig};
2019
use rustc_feature::UnstableFeatures;
2120
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
2221
use rustc_span::source_map::{FileName, FilePathMapping};
@@ -1248,8 +1247,8 @@ pub const fn default_lib_output() -> CrateType {
12481247
CrateType::Rlib
12491248
}
12501249

1251-
fn default_configuration(sess: &Session) -> CrateConfig {
1252-
// NOTE: This should be kept in sync with `CrateCheckConfig::fill_well_known` below.
1250+
fn default_configuration(sess: &Session) -> Cfg<Symbol> {
1251+
// NOTE: This should be kept in sync with `CheckCfg::<Symbol>::fill_well_known` below.
12531252
let end = &sess.target.endian;
12541253
let arch = &sess.target.arch;
12551254
let wordsz = sess.target.pointer_width.to_string();
@@ -1265,7 +1264,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
12651264
sess.emit_fatal(err);
12661265
});
12671266

1268-
let mut ret = CrateConfig::default();
1267+
let mut ret = Cfg::default();
12691268
ret.reserve(7); // the minimum number of insertions
12701269
// Target bindings.
12711270
ret.insert((sym::target_os, Some(Symbol::intern(os))));
@@ -1358,15 +1357,17 @@ fn default_configuration(sess: &Session) -> CrateConfig {
13581357
ret
13591358
}
13601359

1361-
/// Converts the crate `cfg!` configuration from `String` to `Symbol`.
1362-
/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
1363-
/// but the symbol interner is not yet set up then, so we must convert it later.
1364-
pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig {
1365-
cfg.into_iter().map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b)))).collect()
1366-
}
1360+
/// The parsed `--cfg` options that define the compilation environment of the
1361+
/// crate, used to drive conditional compilation. `T` is always `String` or
1362+
/// `Symbol`. Strings are used temporarily very early on. Once the the main
1363+
/// symbol interner is running, they are converted to symbols.
1364+
///
1365+
/// An `FxIndexSet` is used to ensure deterministic ordering of error messages
1366+
/// relating to `--cfg`.
1367+
pub type Cfg<T> = FxIndexSet<(T, Option<T>)>;
13671368

1368-
/// The parsed `--check-cfg` options
1369-
pub struct CheckCfg<T = String> {
1369+
/// The parsed `--check-cfg` options. The `<T>` structure is similar to `Cfg`.
1370+
pub struct CheckCfg<T> {
13701371
/// Is well known names activated
13711372
pub exhaustive_names: bool,
13721373
/// Is well known values activated
@@ -1385,8 +1386,8 @@ impl<T> Default for CheckCfg<T> {
13851386
}
13861387
}
13871388

1388-
impl<T> CheckCfg<T> {
1389-
fn map_data<O: Eq + Hash>(self, f: impl Fn(T) -> O) -> CheckCfg<O> {
1389+
impl CheckCfg<String> {
1390+
pub fn intern(self) -> CheckCfg<Symbol> {
13901391
CheckCfg {
13911392
exhaustive_names: self.exhaustive_names,
13921393
exhaustive_values: self.exhaustive_values,
@@ -1395,10 +1396,10 @@ impl<T> CheckCfg<T> {
13951396
.into_iter()
13961397
.map(|(name, values)| {
13971398
(
1398-
f(name),
1399+
Symbol::intern(&name),
13991400
match values {
14001401
ExpectedValues::Some(values) => ExpectedValues::Some(
1401-
values.into_iter().map(|b| b.map(|b| f(b))).collect(),
1402+
values.into_iter().map(|b| b.map(|b| Symbol::intern(&b))).collect(),
14021403
),
14031404
ExpectedValues::Any => ExpectedValues::Any,
14041405
},
@@ -1441,14 +1442,7 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
14411442
}
14421443
}
14431444

1444-
/// Converts the crate `--check-cfg` options from `String` to `Symbol`.
1445-
/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
1446-
/// but the symbol interner is not yet set up then, so we must convert it later.
1447-
pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
1448-
cfg.map_data(|s| Symbol::intern(&s))
1449-
}
1450-
1451-
impl CrateCheckConfig {
1445+
impl CheckCfg<Symbol> {
14521446
pub fn fill_well_known(&mut self, current_target: &Target) {
14531447
if !self.exhaustive_values && !self.exhaustive_names {
14541448
return;
@@ -1588,7 +1582,13 @@ impl CrateCheckConfig {
15881582
}
15891583
}
15901584

1591-
pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {
1585+
pub fn build_configuration(sess: &Session, user_cfg: Cfg<String>) -> Cfg<Symbol> {
1586+
// We can now intern these strings.
1587+
let mut user_cfg: Cfg<Symbol> = user_cfg
1588+
.into_iter()
1589+
.map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b))))
1590+
.collect();
1591+
15921592
// Combine the configuration requested by the session (command line) with
15931593
// some default and generated configuration items.
15941594
let default_cfg = default_configuration(sess);

0 commit comments

Comments
 (0)