Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_interface cleanups #117268

Merged
merged 7 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4054,7 +4054,6 @@ dependencies = [
"rustc_hir_analysis",
"rustc_hir_typeck",
"rustc_incremental",
"rustc_index",
"rustc_lint",
"rustc_macros",
"rustc_metadata",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ fn run_compiler(
return Ok(());
}

let cfg = interface::parse_cfgspecs(&early_error_handler, matches.opt_strs("cfg"));
let cfg = interface::parse_cfg(&early_error_handler, matches.opt_strs("cfg"));
let check_cfg = interface::parse_check_cfg(&early_error_handler, matches.opt_strs("check-cfg"));
let (odir, ofile) = make_output(&matches);
let mut config = interface::Config {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ rustc_middle = { path = "../rustc_middle" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_incremental = { path = "../rustc_incremental" }
rustc_index = { path = "../rustc_index" }
rustc_traits = { path = "../rustc_traits" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
})
}

/// This is a callback from `rustc_ast` as it cannot access the implicit state
/// This is a callback from `rustc_errors` as it cannot access the implicit state
/// in `rustc_middle` otherwise. It is used when diagnostic messages are
/// emitted and stores them in the current query, if there is one.
fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) {
Expand Down
35 changes: 20 additions & 15 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ use rustc_middle::{bug, ty};
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt;
use rustc_query_system::query::print_query_stack;
use rustc_session::config::{self, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames};
use rustc_session::parse::{CrateConfig, ParseSess};
use rustc_session::config::{
self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames,
};
use rustc_session::parse::ParseSess;
use rustc_session::CompilerIO;
use rustc_session::Session;
use rustc_session::{lint, EarlyErrorHandler};
Expand Down Expand Up @@ -61,14 +63,13 @@ impl Compiler {
}
}

/// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
pub fn parse_cfgspecs(
handler: &EarlyErrorHandler,
cfgspecs: Vec<String>,
) -> FxHashSet<(String, Option<String>)> {
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
pub fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg<String> {
// This creates a short-lived `SessionGlobals`, containing an interner. The
// parsed values are converted from symbols to strings before exiting
// because the symbols are meaningless once the interner is gone.
rustc_span::create_default_session_if_not_set_then(move |_| {
let cfg = cfgspecs
.into_iter()
cfgs.into_iter()
.map(|s| {
let sess = ParseSess::with_silent_emitter(Some(format!(
"this error occurred on the command line: `--cfg={s}`"
Expand Down Expand Up @@ -97,7 +98,10 @@ pub fn parse_cfgspecs(
}
MetaItemKind::NameValue(..) | MetaItemKind::Word => {
let ident = meta_item.ident().expect("multi-segment cfg key");
return (ident.name, meta_item.value_str());
return (
ident.name.to_string(),
meta_item.value_str().map(|sym| sym.to_string()),
);
}
}
}
Expand All @@ -118,13 +122,14 @@ pub fn parse_cfgspecs(
error!(r#"expected `key` or `key="value"`"#);
}
})
.collect::<CrateConfig>();
cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect()
.collect::<Cfg<String>>()
})
}

/// Converts strings provided as `--check-cfg [specs]` into a `CheckCfg`.
pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg {
pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -> CheckCfg<String> {
// The comment about `SessionGlobals` and symbols in `parse_cfg` above
// applies here too.
rustc_span::create_default_session_if_not_set_then(move |_| {
// If any --check-cfg is passed then exhaustive_values and exhaustive_names
// are enabled by default.
Expand Down Expand Up @@ -372,8 +377,8 @@ pub struct Config {
pub opts: config::Options,

/// cfg! configuration in addition to the default ones
pub crate_cfg: FxHashSet<(String, Option<String>)>,
pub crate_check_cfg: CheckCfg,
pub crate_cfg: Cfg<String>,
pub crate_check_cfg: CheckCfg<String>,

pub input: Input,
pub output_dir: Option<PathBuf>,
Expand Down
29 changes: 10 additions & 19 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
#![allow(rustc::bad_opt_access)]
use crate::interface::parse_cfgspecs;

use rustc_data_structures::fx::FxHashSet;
use crate::interface::parse_cfg;
use rustc_data_structures::profiling::TimePassesFormat;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::rustc_optgroups;
use rustc_session::config::Cfg;
use rustc_session::config::DebugInfo;
use rustc_session::config::Input;
use rustc_session::config::InstrumentXRay;
use rustc_session::config::LinkSelfContained;
use rustc_session::config::Polonius;
use rustc_session::config::TraitSolver;
use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
use rustc_session::config::{build_configuration, build_session_options};
use rustc_session::config::{
BranchProtection, Externs, OomStrategy, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
ProcMacroExecutionStrategy, SymbolManglingVersion, WasiExecModel,
Expand All @@ -31,26 +30,18 @@ use rustc_span::FileName;
use rustc_span::SourceFileHashAlgorithm;
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};

use std::collections::{BTreeMap, BTreeSet};
use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};
use std::sync::Arc;

type CfgSpecs = FxHashSet<(String, Option<String>)>;

fn build_session_options_and_crate_config(
fn mk_session(
handler: &mut EarlyErrorHandler,
matches: getopts::Matches,
) -> (Options, CfgSpecs) {
let sessopts = build_session_options(handler, &matches);
let cfg = parse_cfgspecs(handler, matches.opt_strs("cfg"));
(sessopts, cfg)
}

fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, CfgSpecs) {
) -> (Session, Cfg<String>) {
let registry = registry::Registry::new(&[]);
let (sessopts, cfg) = build_session_options_and_crate_config(handler, matches);
let sessopts = build_session_options(handler, &matches);
let cfg = parse_cfg(handler, matches.opt_strs("cfg"));
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
let io = CompilerIO {
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
Expand Down Expand Up @@ -141,7 +132,7 @@ fn test_switch_implies_cfg_test() {
let matches = optgroups().parse(&["--test".to_string()]).unwrap();
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
let (sess, cfg) = mk_session(&mut handler, matches);
let cfg = build_configuration(&sess, to_crate_config(cfg));
let cfg = build_configuration(&sess, cfg);
assert!(cfg.contains(&(sym::test, None)));
});
}
Expand All @@ -153,7 +144,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
let (sess, cfg) = mk_session(&mut handler, matches);
let cfg = build_configuration(&sess, to_crate_config(cfg));
let cfg = build_configuration(&sess, cfg);
let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
assert!(test_items.next().is_some());
assert!(test_items.next().is_none());
Expand Down Expand Up @@ -880,6 +871,6 @@ fn test_edition_parsing() {
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());

let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
let (sessopts, _) = build_session_options_and_crate_config(&mut handler, matches);
let sessopts = build_session_options(&mut handler, &matches);
assert!(sessopts.edition == Edition::Edition2018)
}
20 changes: 10 additions & 10 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ use info;
use libloading::Library;
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::FxHashMap;
#[cfg(parallel_compiler)]
use rustc_data_structures::sync;
use rustc_errors::registry::Registry;
use rustc_parse::validate_attr;
use rustc_session as session;
use rustc_session::config::CheckCfg;
use rustc_session::config::{self, CrateType};
use rustc_session::config::{OutFileName, OutputFilenames, OutputTypes};
use rustc_session::config::{
self, Cfg, CheckCfg, CrateType, OutFileName, OutputFilenames, OutputTypes,
};
use rustc_session::filesearch::sysroot_candidates;
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
use rustc_session::parse::CrateConfig;
use rustc_session::{filesearch, output, Session};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
Expand All @@ -38,7 +37,7 @@ pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
/// This is performed by checking whether a set of permitted features
/// is available on the target machine, by querying the codegen backend.
pub fn add_configuration(
cfg: &mut CrateConfig,
cfg: &mut Cfg<Symbol>,
sess: &mut Session,
codegen_backend: &dyn CodegenBackend,
) {
Expand All @@ -60,8 +59,8 @@ pub fn add_configuration(
pub fn create_session(
handler: &EarlyErrorHandler,
sopts: config::Options,
cfg: FxHashSet<(String, Option<String>)>,
check_cfg: CheckCfg,
cfg: Cfg<String>,
check_cfg: CheckCfg<String>,
locale_resources: &'static [&'static str],
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
io: CompilerIO,
Expand Down Expand Up @@ -121,12 +120,13 @@ pub fn create_session(

codegen_backend.init(&sess);

let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
let mut cfg = config::build_configuration(&sess, cfg);
add_configuration(&mut cfg, &mut sess, &*codegen_backend);

let mut check_cfg = config::to_crate_check_config(check_cfg);
let mut check_cfg = check_cfg.intern();
check_cfg.fill_well_known(&sess.target);

// These configs use symbols, rather than strings.
sess.parse_sess.config = cfg;
sess.parse_sess.check_config = check_cfg;

Expand Down
52 changes: 26 additions & 26 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{lint, HashStableContext};
use crate::{EarlyErrorHandler, Session};

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
use rustc_target::abi::Align;
use rustc_target::spec::LinkSelfContainedComponents;
use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};

use crate::parse::{CrateCheckConfig, CrateConfig};
use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
use rustc_span::source_map::{FileName, FilePathMapping};
Expand Down Expand Up @@ -1248,8 +1247,8 @@ pub const fn default_lib_output() -> CrateType {
CrateType::Rlib
}

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

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

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

/// The parsed `--check-cfg` options
pub struct CheckCfg<T = String> {
/// The parsed `--check-cfg` options. The `<T>` structure is similar to `Cfg`.
pub struct CheckCfg<T> {
/// Is well known names activated
pub exhaustive_names: bool,
/// Is well known values activated
Expand All @@ -1385,8 +1386,8 @@ impl<T> Default for CheckCfg<T> {
}
}

impl<T> CheckCfg<T> {
fn map_data<O: Eq + Hash>(self, f: impl Fn(T) -> O) -> CheckCfg<O> {
impl CheckCfg<String> {
pub fn intern(self) -> CheckCfg<Symbol> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

CheckCfg {
exhaustive_names: self.exhaustive_names,
exhaustive_values: self.exhaustive_values,
Expand All @@ -1395,10 +1396,10 @@ impl<T> CheckCfg<T> {
.into_iter()
.map(|(name, values)| {
(
f(name),
Symbol::intern(&name),
match values {
ExpectedValues::Some(values) => ExpectedValues::Some(
values.into_iter().map(|b| b.map(|b| f(b))).collect(),
values.into_iter().map(|b| b.map(|b| Symbol::intern(&b))).collect(),
),
ExpectedValues::Any => ExpectedValues::Any,
},
Expand Down Expand Up @@ -1441,14 +1442,7 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
}
}

/// Converts the crate `--check-cfg` options from `String` to `Symbol`.
/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
/// but the symbol interner is not yet set up then, so we must convert it later.
Comment on lines -1444 to -1446
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it is worth keeping this comment? by moving it to the intern function maybe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other new comments that communicate the same ideas, so I think that's good enough.

pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
cfg.map_data(|s| Symbol::intern(&s))
}

impl CrateCheckConfig {
impl CheckCfg<Symbol> {
pub fn fill_well_known(&mut self, current_target: &Target) {
if !self.exhaustive_values && !self.exhaustive_names {
return;
Expand Down Expand Up @@ -1588,7 +1582,13 @@ impl CrateCheckConfig {
}
}

pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {
pub fn build_configuration(sess: &Session, user_cfg: Cfg<String>) -> 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
// some default and generated configuration items.
let default_cfg = default_configuration(sess);
Expand Down
Loading
Loading