Skip to content

Commit d96bdbe

Browse files
Rollup merge of #117376 - nnethercote:rustc_interface-more, r=oli-obk
More `rustc_interface` cleanups In particular, following up #117268 with more improvement to `--cfg`/`--check-cfg` handling. r? ``@oli-obk``
2 parents 784f04b + 0c381ec commit d96bdbe

File tree

11 files changed

+283
-410
lines changed

11 files changed

+283
-410
lines changed

compiler/rustc_driver_impl/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,11 @@ fn run_compiler(
317317
return Ok(());
318318
}
319319

320-
let cfg = interface::parse_cfg(&early_error_handler, matches.opt_strs("cfg"));
321-
let check_cfg = interface::parse_check_cfg(&early_error_handler, matches.opt_strs("check-cfg"));
322320
let (odir, ofile) = make_output(&matches);
323321
let mut config = interface::Config {
324322
opts: sopts,
325-
crate_cfg: cfg,
326-
crate_check_cfg: check_cfg,
323+
crate_cfg: matches.opt_strs("cfg"),
324+
crate_check_cfg: matches.opt_strs("check-cfg"),
327325
input: Input::File(PathBuf::new()),
328326
output_file: ofile,
329327
output_dir: odir,

compiler/rustc_interface/src/callbacks.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ fn track_diagnostic(diagnostic: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnost
3333
tls::with_context_opt(|icx| {
3434
if let Some(icx) = icx {
3535
if let Some(diagnostics) = icx.diagnostics {
36-
let mut diagnostics = diagnostics.lock();
37-
diagnostics.extend(Some(diagnostic.clone()));
38-
std::mem::drop(diagnostics);
36+
diagnostics.lock().extend(Some(diagnostic.clone()));
3937
}
4038

4139
// Diagnostics are tracked, we can ignore the dependency.

compiler/rustc_interface/src/interface.rs

+226-256
Large diffs are not rendered by default.

compiler/rustc_interface/src/passes.rs

+15-33
Original file line numberDiff line numberDiff line change
@@ -392,34 +392,16 @@ fn generated_output_paths(
392392
out_filenames
393393
}
394394

395-
// Runs `f` on every output file path and returns the first non-None result, or None if `f`
396-
// returns None for every file path.
397-
fn check_output<F, T>(output_paths: &[PathBuf], f: F) -> Option<T>
398-
where
399-
F: Fn(&PathBuf) -> Option<T>,
400-
{
401-
for output_path in output_paths {
402-
if let Some(result) = f(output_path) {
403-
return Some(result);
404-
}
405-
}
406-
None
407-
}
408-
409395
fn output_contains_path(output_paths: &[PathBuf], input_path: &Path) -> bool {
410396
let input_path = try_canonicalize(input_path).ok();
411397
if input_path.is_none() {
412398
return false;
413399
}
414-
let check = |output_path: &PathBuf| {
415-
if try_canonicalize(output_path).ok() == input_path { Some(()) } else { None }
416-
};
417-
check_output(output_paths, check).is_some()
400+
output_paths.iter().any(|output_path| try_canonicalize(output_path).ok() == input_path)
418401
}
419402

420-
fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<PathBuf> {
421-
let check = |output_path: &PathBuf| output_path.is_dir().then(|| output_path.clone());
422-
check_output(output_paths, check)
403+
fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<&PathBuf> {
404+
output_paths.iter().find(|output_path| output_path.is_dir())
423405
}
424406

425407
fn escape_dep_filename(filename: &str) -> String {
@@ -602,9 +584,7 @@ fn output_filenames(tcx: TyCtxt<'_>, (): ()) -> Arc<OutputFilenames> {
602584
let (_, krate) = &*tcx.resolver_for_lowering(()).borrow();
603585
let crate_name = tcx.crate_name(LOCAL_CRATE);
604586

605-
// FIXME: rustdoc passes &[] instead of &krate.attrs here
606587
let outputs = util::build_output_filenames(&krate.attrs, sess);
607-
608588
let output_paths =
609589
generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name);
610590

@@ -882,16 +862,18 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
882862

883863
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, tr));
884864

885-
// A slightly edited version of the code in `rustc_trait_selection::traits::vtable::vtable_entries`,
886-
// that works without self type and just counts number of entries.
865+
// A slightly edited version of the code in
866+
// `rustc_trait_selection::traits::vtable::vtable_entries`, that works without self
867+
// type and just counts number of entries.
887868
//
888-
// Note that this is technically wrong, for traits which have associated types in supertraits:
869+
// Note that this is technically wrong, for traits which have associated types in
870+
// supertraits:
889871
//
890872
// trait A: AsRef<Self::T> + AsRef<()> { type T; }
891873
//
892-
// Without self type we can't normalize `Self::T`, so we can't know if `AsRef<Self::T>` and
893-
// `AsRef<()>` are the same trait, thus we assume that those are different, and potentially
894-
// over-estimate how many vtable entries there are.
874+
// Without self type we can't normalize `Self::T`, so we can't know if `AsRef<Self::T>`
875+
// and `AsRef<()>` are the same trait, thus we assume that those are different, and
876+
// potentially over-estimate how many vtable entries there are.
895877
//
896878
// Similarly this is wrong for traits that have methods with possibly-impossible bounds.
897879
// For example:
@@ -918,10 +900,10 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
918900
let own_existential_entries =
919901
tcx.own_existential_vtable_entries(trait_ref.def_id());
920902

921-
// The original code here ignores the method if its predicates are impossible.
922-
// We can't really do that as, for example, all not trivial bounds on generic
923-
// parameters are impossible (since we don't know the parameters...),
924-
// see the comment above.
903+
// The original code here ignores the method if its predicates are
904+
// impossible. We can't really do that as, for example, all not trivial
905+
// bounds on generic parameters are impossible (since we don't know the
906+
// parameters...), see the comment above.
925907
entries_ignoring_upcasting += own_existential_entries.len();
926908

927909
if emit_vptr {

compiler/rustc_interface/src/tests.rs

+9-23
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,29 @@
22
use crate::interface::parse_cfg;
33
use rustc_data_structures::profiling::TimePassesFormat;
44
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
5-
use rustc_session::config::rustc_optgroups;
6-
use rustc_session::config::Cfg;
7-
use rustc_session::config::DebugInfo;
8-
use rustc_session::config::Input;
9-
use rustc_session::config::InstrumentXRay;
10-
use rustc_session::config::LinkSelfContained;
11-
use rustc_session::config::Polonius;
12-
use rustc_session::config::TraitSolver;
13-
use rustc_session::config::{build_configuration, build_session_options};
145
use rustc_session::config::{
15-
BranchProtection, Externs, OomStrategy, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
16-
ProcMacroExecutionStrategy, SymbolManglingVersion, WasiExecModel,
6+
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
7+
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, Input,
8+
InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli,
9+
MirSpanview, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
10+
Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion,
11+
TraitSolver, WasiExecModel,
1712
};
18-
use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
19-
use rustc_session::config::{DumpMonoStatsFormat, MirSpanview};
20-
use rustc_session::config::{ErrorOutputType, ExternLocation, LocationDetail, Options, Strip};
21-
use rustc_session::config::{InstrumentCoverage, Passes};
2213
use rustc_session::lint::Level;
2314
use rustc_session::search_paths::SearchPath;
2415
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
25-
use rustc_session::{build_session, getopts, Session};
26-
use rustc_session::{CompilerIO, EarlyErrorHandler};
16+
use rustc_session::{build_session, getopts, CompilerIO, EarlyErrorHandler, Session};
2717
use rustc_span::edition::{Edition, DEFAULT_EDITION};
2818
use rustc_span::symbol::sym;
29-
use rustc_span::FileName;
30-
use rustc_span::SourceFileHashAlgorithm;
19+
use rustc_span::{FileName, SourceFileHashAlgorithm};
3120
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
3221
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
3322
use std::collections::{BTreeMap, BTreeSet};
3423
use std::num::NonZeroUsize;
3524
use std::path::{Path, PathBuf};
3625
use std::sync::Arc;
3726

38-
fn mk_session(
39-
handler: &mut EarlyErrorHandler,
40-
matches: getopts::Matches,
41-
) -> (Session, Cfg<String>) {
27+
fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Session, Cfg) {
4228
let registry = registry::Registry::new(&[]);
4329
let sessopts = build_session_options(handler, &matches);
4430
let cfg = parse_cfg(handler, matches.opt_strs("cfg"));

compiler/rustc_interface/src/util.rs

+10-23
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ pub type MakeBackendFn = fn() -> Box<dyn CodegenBackend>;
3636
///
3737
/// This is performed by checking whether a set of permitted features
3838
/// is available on the target machine, by querying the codegen backend.
39-
pub fn add_configuration(
40-
cfg: &mut Cfg<Symbol>,
41-
sess: &mut Session,
42-
codegen_backend: &dyn CodegenBackend,
43-
) {
39+
pub fn add_configuration(cfg: &mut Cfg, sess: &mut Session, codegen_backend: &dyn CodegenBackend) {
4440
let tf = sym::target_feature;
4541

4642
let unstable_target_features = codegen_backend.target_features(sess, true);
@@ -59,8 +55,8 @@ pub fn add_configuration(
5955
pub fn create_session(
6056
handler: &EarlyErrorHandler,
6157
sopts: config::Options,
62-
cfg: Cfg<String>,
63-
check_cfg: CheckCfg<String>,
58+
cfg: Cfg,
59+
mut check_cfg: CheckCfg,
6460
locale_resources: &'static [&'static str],
6561
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
6662
io: CompilerIO,
@@ -123,7 +119,6 @@ pub fn create_session(
123119
let mut cfg = config::build_configuration(&sess, cfg);
124120
add_configuration(&mut cfg, &mut sess, &*codegen_backend);
125121

126-
let mut check_cfg = check_cfg.intern();
127122
check_cfg.fill_well_known(&sess.target);
128123

129124
// These configs use symbols, rather than strings.
@@ -487,21 +482,6 @@ fn categorize_crate_type(s: Symbol) -> Option<CrateType> {
487482
}
488483

489484
pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<CrateType> {
490-
// Unconditionally collect crate types from attributes to make them used
491-
let attr_types: Vec<CrateType> = attrs
492-
.iter()
493-
.filter_map(|a| {
494-
if a.has_name(sym::crate_type) {
495-
match a.value_str() {
496-
Some(s) => categorize_crate_type(s),
497-
_ => None,
498-
}
499-
} else {
500-
None
501-
}
502-
})
503-
.collect();
504-
505485
// If we're generating a test executable, then ignore all other output
506486
// styles at all other locations
507487
if session.opts.test {
@@ -515,6 +495,13 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
515495
#[allow(rustc::bad_opt_access)]
516496
let mut base = session.opts.crate_types.clone();
517497
if base.is_empty() {
498+
let attr_types = attrs.iter().filter_map(|a| {
499+
if a.has_name(sym::crate_type) && let Some(s) = a.value_str() {
500+
categorize_crate_type(s)
501+
} else {
502+
None
503+
}
504+
});
518505
base.extend(attr_types);
519506
if base.is_empty() {
520507
base.push(output::default_output_for_target(session));

compiler/rustc_session/src/config.rs

+10-51
Original file line numberDiff line numberDiff line change
@@ -1247,8 +1247,8 @@ pub const fn default_lib_output() -> CrateType {
12471247
CrateType::Rlib
12481248
}
12491249

1250-
fn default_configuration(sess: &Session) -> Cfg<Symbol> {
1251-
// NOTE: This should be kept in sync with `CheckCfg::<Symbol>::fill_well_known` below.
1250+
fn default_configuration(sess: &Session) -> Cfg {
1251+
// NOTE: This should be kept in sync with `CheckCfg::fill_well_known` below.
12521252
let end = &sess.target.endian;
12531253
let arch = &sess.target.arch;
12541254
let wordsz = sess.target.pointer_width.to_string();
@@ -1358,56 +1358,21 @@ fn default_configuration(sess: &Session) -> Cfg<Symbol> {
13581358
}
13591359

13601360
/// 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.
1361+
/// crate, used to drive conditional compilation.
13641362
///
13651363
/// An `FxIndexSet` is used to ensure deterministic ordering of error messages
13661364
/// relating to `--cfg`.
1367-
pub type Cfg<T> = FxIndexSet<(T, Option<T>)>;
1365+
pub type Cfg = FxIndexSet<(Symbol, Option<Symbol>)>;
13681366

1369-
/// The parsed `--check-cfg` options. The `<T>` structure is similar to `Cfg`.
1370-
pub struct CheckCfg<T> {
1367+
/// The parsed `--check-cfg` options.
1368+
#[derive(Default)]
1369+
pub struct CheckCfg {
13711370
/// Is well known names activated
13721371
pub exhaustive_names: bool,
13731372
/// Is well known values activated
13741373
pub exhaustive_values: bool,
13751374
/// All the expected values for a config name
1376-
pub expecteds: FxHashMap<T, ExpectedValues<T>>,
1377-
}
1378-
1379-
impl<T> Default for CheckCfg<T> {
1380-
fn default() -> Self {
1381-
CheckCfg {
1382-
exhaustive_names: false,
1383-
exhaustive_values: false,
1384-
expecteds: FxHashMap::default(),
1385-
}
1386-
}
1387-
}
1388-
1389-
impl CheckCfg<String> {
1390-
pub fn intern(self) -> CheckCfg<Symbol> {
1391-
CheckCfg {
1392-
exhaustive_names: self.exhaustive_names,
1393-
exhaustive_values: self.exhaustive_values,
1394-
expecteds: self
1395-
.expecteds
1396-
.into_iter()
1397-
.map(|(name, values)| {
1398-
(
1399-
Symbol::intern(&name),
1400-
match values {
1401-
ExpectedValues::Some(values) => ExpectedValues::Some(
1402-
values.into_iter().map(|b| b.map(|b| Symbol::intern(&b))).collect(),
1403-
),
1404-
ExpectedValues::Any => ExpectedValues::Any,
1405-
},
1406-
)
1407-
})
1408-
.collect(),
1409-
}
1410-
}
1375+
pub expecteds: FxHashMap<Symbol, ExpectedValues<Symbol>>,
14111376
}
14121377

14131378
pub enum ExpectedValues<T> {
@@ -1442,7 +1407,7 @@ impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
14421407
}
14431408
}
14441409

1445-
impl CheckCfg<Symbol> {
1410+
impl CheckCfg {
14461411
pub fn fill_well_known(&mut self, current_target: &Target) {
14471412
if !self.exhaustive_values && !self.exhaustive_names {
14481413
return;
@@ -1582,13 +1547,7 @@ impl CheckCfg<Symbol> {
15821547
}
15831548
}
15841549

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-
1550+
pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
15921551
// Combine the configuration requested by the session (command line) with
15931552
// some default and generated configuration items.
15941553
let default_cfg = default_configuration(sess);

compiler/rustc_session/src/parse.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ pub fn add_feature_diagnostics_for_issue(
188188
pub struct ParseSess {
189189
pub span_diagnostic: Handler,
190190
pub unstable_features: UnstableFeatures,
191-
pub config: Cfg<Symbol>,
192-
pub check_config: CheckCfg<Symbol>,
191+
pub config: Cfg,
192+
pub check_config: CheckCfg,
193193
pub edition: Edition,
194194
/// Places where raw identifiers were used. This is used to avoid complaining about idents
195195
/// clashing with keywords in new editions.

src/librustdoc/core.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use rustc_lint::{late_lint_mod, MissingDoc};
1414
use rustc_middle::hir::nested_filter;
1515
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
1616
use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks};
17+
use rustc_session::lint;
1718
use rustc_session::Session;
18-
use rustc_session::{lint, EarlyErrorHandler};
1919
use rustc_span::symbol::sym;
2020
use rustc_span::{source_map, Span};
2121

@@ -175,7 +175,6 @@ pub(crate) fn new_handler(
175175

176176
/// Parse, resolve, and typecheck the given crate.
177177
pub(crate) fn create_config(
178-
handler: &EarlyErrorHandler,
179178
RustdocOptions {
180179
input,
181180
crate_name,
@@ -255,8 +254,8 @@ pub(crate) fn create_config(
255254

256255
interface::Config {
257256
opts: sessopts,
258-
crate_cfg: interface::parse_cfg(handler, cfgs),
259-
crate_check_cfg: interface::parse_check_cfg(handler, check_cfgs),
257+
crate_cfg: cfgs,
258+
crate_check_cfg: check_cfgs,
260259
input,
261260
output_file: None,
262261
output_dir: None,

0 commit comments

Comments
 (0)