Skip to content

Commit

Permalink
Unrolled build for rust-lang#122811
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#122811 - nnethercote:mv-SourceMap-init, r=WaffleLapkin

Move `SourceMap` initialization

So it happens at the same time as `SessionGlobals` initialization, rather than shortly afterward.

r? `@WaffleLapkin`
  • Loading branch information
rust-timer committed Apr 16, 2024
2 parents 468f115 + 9b0ced0 commit 2ce16d1
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 177 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn def_path_hash_depends_on_crate_id() {
// the crate by changing the crate disambiguator (e.g. via bumping the
// crate's version number).

create_session_globals_then(Edition::Edition2024, || {
create_session_globals_then(Edition::Edition2024, None, || {
let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], "");
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");

Expand Down
109 changes: 61 additions & 48 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_ast::{LitKind, MetaItemKind};
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::defer;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::jobserver;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lrc;
use rustc_errors::registry::Registry;
Expand All @@ -21,7 +22,7 @@ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileN
use rustc_session::filesearch::{self, sysroot_candidates};
use rustc_session::parse::ParseSess;
use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
use rustc_span::source_map::FileLoader;
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
use rustc_span::symbol::sym;
use rustc_span::FileName;
use std::path::PathBuf;
Expand Down Expand Up @@ -323,6 +324,18 @@ pub struct Config {
pub expanded_args: Vec<String>,
}

/// Initialize jobserver before getting `jobserver::client` and `build_session`.
pub(crate) fn initialize_checked_jobserver(early_dcx: &EarlyDiagCtxt) {
jobserver::initialize_checked(|err| {
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
early_dcx
.early_struct_warn(err)
.with_note("the build environment is likely misconfigured")
.emit()
});
}

// JUSTIFICATION: before session exists, only config
#[allow(rustc::bad_opt_access)]
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
Expand All @@ -334,20 +347,25 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se

// Check jobserver before run_in_thread_pool_with_globals, which call jobserver::acquire_thread
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
early_dcx.initialize_checked_jobserver();
initialize_checked_jobserver(&early_dcx);

crate::callbacks::setup_callbacks();

let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);
let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
let path_mapping = config.opts.file_path_mapping();
let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target);

util::run_in_thread_pool_with_globals(
config.opts.edition,
config.opts.unstable_opts.threads,
SourceMapInputs { file_loader, path_mapping, hash_kind },
|current_gcx| {
crate::callbacks::setup_callbacks();

// The previous `early_dcx` can't be reused here because it doesn't
// impl `Send`. Creating a new one is fine.
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);

let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());

let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);

let codegen_backend = match config.make_codegen_backend {
None => util::get_codegen_backend(
&early_dcx,
Expand All @@ -372,9 +390,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
config.opts.unstable_opts.translate_directionality_markers,
) {
Ok(bundle) => bundle,
Err(e) => {
early_dcx.early_fatal(format!("failed to load fluent bundle: {e}"));
}
Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
};

let mut locale_resources = Vec::from(config.locale_resources);
Expand All @@ -393,7 +409,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
config.registry.clone(),
locale_resources,
config.lint_caps,
config.file_loader,
target,
sysroot,
util::rustc_version_str().unwrap_or("unknown"),
Expand Down Expand Up @@ -440,45 +455,43 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
current_gcx,
};

rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || {
// There are two paths out of `f`.
// - Normal exit.
// - Panic, e.g. triggered by `abort_if_errors`.
//
// We must run `finish_diagnostics` in both cases.
let res = {
// If `f` panics, `finish_diagnostics` will run during
// unwinding because of the `defer`.
let mut guar = None;
let sess_abort_guard = defer(|| {
guar = compiler.sess.finish_diagnostics(&config.registry);
});

let res = f(&compiler);

// If `f` doesn't panic, `finish_diagnostics` will run
// normally when `sess_abort_guard` is dropped.
drop(sess_abort_guard);

// If `finish_diagnostics` emits errors (e.g. stashed
// errors) we can't return an error directly, because the
// return type of this function is `R`, not `Result<R, E>`.
// But we need to communicate the errors' existence to the
// caller, otherwise the caller might mistakenly think that
// no errors occurred and return a zero exit code. So we
// abort (panic) instead, similar to if `f` had panicked.
if guar.is_some() {
compiler.sess.dcx().abort_if_errors();
}
// There are two paths out of `f`.
// - Normal exit.
// - Panic, e.g. triggered by `abort_if_errors`.
//
// We must run `finish_diagnostics` in both cases.
let res = {
// If `f` panics, `finish_diagnostics` will run during
// unwinding because of the `defer`.
let mut guar = None;
let sess_abort_guard = defer(|| {
guar = compiler.sess.finish_diagnostics(&config.registry);
});

let res = f(&compiler);

// If `f` doesn't panic, `finish_diagnostics` will run
// normally when `sess_abort_guard` is dropped.
drop(sess_abort_guard);

// If `finish_diagnostics` emits errors (e.g. stashed
// errors) we can't return an error directly, because the
// return type of this function is `R`, not `Result<R, E>`.
// But we need to communicate the errors' existence to the
// caller, otherwise the caller might mistakenly think that
// no errors occurred and return a zero exit code. So we
// abort (panic) instead, similar to if `f` had panicked.
if guar.is_some() {
compiler.sess.dcx().abort_if_errors();
}

res
};
res
};

let prof = compiler.sess.prof.clone();
prof.generic_activity("drop_compiler").run(move || drop(compiler));
let prof = compiler.sess.prof.clone();
prof.generic_activity("drop_compiler").run(move || drop(compiler));

res
})
res
},
)
}
Expand Down
98 changes: 48 additions & 50 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(rustc::bad_opt_access)]
use crate::interface::parse_cfg;
use crate::interface::{initialize_checked_jobserver, parse_cfg};
use rustc_data_structures::profiling::TimePassesFormat;
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
use rustc_session::config::{
Expand All @@ -16,6 +16,7 @@ use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
use rustc_span::symbol::sym;
use rustc_span::{FileName, SourceFileHashAlgorithm};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
Expand All @@ -25,42 +26,52 @@ use std::num::NonZero;
use std::path::{Path, PathBuf};
use std::sync::Arc;

fn mk_session(matches: getopts::Matches) -> (Session, Cfg) {
fn sess_and_cfg<F>(args: &[&'static str], f: F)
where
F: FnOnce(Session, Cfg),
{
let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
early_dcx.initialize_checked_jobserver();
initialize_checked_jobserver(&early_dcx);

let registry = registry::Registry::new(&[]);
let matches = optgroups().parse(args).unwrap();
let sessopts = build_session_options(&mut early_dcx, &matches);
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() },
output_dir: None,
output_file: None,
temps_dir,
};

let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());

let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot);
let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target);
let sm_inputs = Some(SourceMapInputs {
file_loader: Box::new(RealFileLoader) as _,
path_mapping: sessopts.file_path_mapping(),
hash_kind,
});

let sess = build_session(
early_dcx,
sessopts,
io,
None,
registry,
vec![],
Default::default(),
None,
target,
sysroot,
"",
None,
Arc::default(),
Default::default(),
);
let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg"));
(sess, cfg)
rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || {
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() },
output_dir: None,
output_file: None,
temps_dir,
};

let sess = build_session(
early_dcx,
sessopts,
io,
None,
registry::Registry::new(&[]),
vec![],
Default::default(),
target,
sysroot,
"",
None,
Arc::default(),
Default::default(),
);
let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg"));
let cfg = build_configuration(&sess, cfg);
f(sess, cfg)
});
}

fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
Expand Down Expand Up @@ -125,21 +136,15 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) {
// When the user supplies --test we should implicitly supply --cfg test
#[test]
fn test_switch_implies_cfg_test() {
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["--test".to_string()]).unwrap();
let (sess, cfg) = mk_session(matches);
let cfg = build_configuration(&sess, cfg);
sess_and_cfg(&["--test"], |_sess, cfg| {
assert!(cfg.contains(&(sym::test, None)));
});
})
}

// When the user supplies --test and --cfg test, don't implicitly add another --cfg test
#[test]
fn test_switch_implies_cfg_test_unless_cfg_test() {
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
let (sess, cfg) = mk_session(matches);
let cfg = build_configuration(&sess, cfg);
sess_and_cfg(&["--test", "--cfg=test"], |_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 All @@ -148,22 +153,15 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {

#[test]
fn test_can_print_warnings() {
rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
let (sess, _) = mk_session(matches);
sess_and_cfg(&["-Awarnings"], |sess, _cfg| {
assert!(!sess.dcx().can_emit_warnings());
});

rustc_span::create_default_session_globals_then(|| {
let matches =
optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
let (sess, _) = mk_session(matches);
sess_and_cfg(&["-Awarnings", "-Dwarnings"], |sess, _cfg| {
assert!(sess.dcx().can_emit_warnings());
});

rustc_span::create_default_session_globals_then(|| {
let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
let (sess, _) = mk_session(matches);
sess_and_cfg(&["-Adead_code"], |sess, _cfg| {
assert!(sess.dcx().can_emit_warnings());
});
}
Expand Down
16 changes: 11 additions & 5 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
use rustc_session::{filesearch, Session};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::source_map::SourceMapInputs;
use rustc_span::symbol::sym;
use rustc_target::spec::Target;
use session::output::{categorize_crate_type, CRATE_TYPES};
Expand Down Expand Up @@ -65,8 +66,9 @@ fn init_stack_size() -> usize {
})
}

pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
edition: Edition,
sm_inputs: SourceMapInputs,
f: F,
) -> R {
// The "thread pool" is a single spawned thread in the non-parallel
Expand All @@ -84,7 +86,9 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: S
// name contains null bytes.
let r = builder
.spawn_scoped(s, move || {
rustc_span::create_session_globals_then(edition, || f(CurrentGcx::new()))
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
f(CurrentGcx::new())
})
})
.unwrap()
.join();
Expand All @@ -100,15 +104,17 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: S
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
edition: Edition,
_threads: usize,
sm_inputs: SourceMapInputs,
f: F,
) -> R {
run_in_thread_with_globals(edition, f)
run_in_thread_with_globals(edition, sm_inputs, f)
}

#[cfg(parallel_compiler)]
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
edition: Edition,
threads: usize,
sm_inputs: SourceMapInputs,
f: F,
) -> R {
use rustc_data_structures::{defer, jobserver, sync::FromDyn};
Expand All @@ -120,7 +126,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());

if !sync::is_dyn_thread_safe() {
return run_in_thread_with_globals(edition, |current_gcx| {
return run_in_thread_with_globals(edition, sm_inputs, |current_gcx| {
// Register the thread for use with the `WorkerLocal` type.
registry.register();

Expand Down Expand Up @@ -169,7 +175,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
// pool. Upon creation, each worker thread created gets a copy of the
// session globals in TLS. This is possible because `SessionGlobals` impls
// `Send` in the parallel compiler.
rustc_span::create_session_globals_then(edition, || {
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
rustc_span::with_session_globals(|session_globals| {
let session_globals = FromDyn::from(session_globals);
builder
Expand Down
Loading

0 comments on commit 2ce16d1

Please sign in to comment.