Skip to content

Commit 0acd1c2

Browse files
committed
Construct SourceMap at the same time as SessionGlobals.
Currently `SourceMap` is constructed slightly later than `SessionGlobals`, and inserted. This commit changes things so they are done at the same time. Benefits: - `SessionGlobals::source_map` changes from `Lock<Option<Lrc<SourceMap>>>` to `Option<Lrc<SourceMap>>`. It's still optional, but mutability isn't required because it's initialized at construction. - `set_source_map` is removed, simplifying `run_compiler`, which is good because that's a critical function and it's nice to make it simpler. This requires moving things around a bit, so the necessary inputs are available when `SessionGlobals` is created, in particular the `loader` and `hash_kind`, which are no longer computed by `build_session`. These inputs are captured by the new `SourceMapInputs` type, which is threaded through various places. And there's a new
1 parent a86fcdb commit 0acd1c2

File tree

10 files changed

+120
-118
lines changed

10 files changed

+120
-118
lines changed

compiler/rustc_hir/src/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn def_path_hash_depends_on_crate_id() {
1414
// the crate by changing the crate disambiguator (e.g. via bumping the
1515
// crate's version number).
1616

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

compiler/rustc_interface/src/interface.rs

+47-47
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileN
1919
use rustc_session::filesearch::{self, sysroot_candidates};
2020
use rustc_session::parse::ParseSess;
2121
use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
22-
use rustc_span::source_map::FileLoader;
22+
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
2323
use rustc_span::symbol::sym;
2424
use rustc_span::FileName;
2525
use std::path::PathBuf;
@@ -331,18 +331,23 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
331331
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
332332
early_dcx.initialize_checked_jobserver();
333333

334+
crate::callbacks::setup_callbacks();
335+
336+
let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
337+
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);
338+
let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
339+
let path_mapping = config.opts.file_path_mapping();
340+
let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target);
341+
334342
util::run_in_thread_pool_with_globals(
335343
config.opts.edition,
336344
config.opts.unstable_opts.threads,
345+
SourceMapInputs { file_loader, path_mapping, hash_kind },
337346
|| {
338-
crate::callbacks::setup_callbacks();
339-
347+
// The previous `early_dcx` can't be reused here because it doesn't
348+
// impl `Send`. Creating a new one is fine.
340349
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
341350

342-
let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
343-
344-
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);
345-
346351
let codegen_backend = match config.make_codegen_backend {
347352
None => util::get_codegen_backend(
348353
&early_dcx,
@@ -367,9 +372,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
367372
config.opts.unstable_opts.translate_directionality_markers,
368373
) {
369374
Ok(bundle) => bundle,
370-
Err(e) => {
371-
early_dcx.early_fatal(format!("failed to load fluent bundle: {e}"));
372-
}
375+
Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
373376
};
374377

375378
let mut locale_resources = Vec::from(config.locale_resources);
@@ -388,7 +391,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
388391
config.registry.clone(),
389392
locale_resources,
390393
config.lint_caps,
391-
config.file_loader,
392394
target,
393395
sysroot,
394396
util::rustc_version_str().unwrap_or("unknown"),
@@ -431,45 +433,43 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
431433
let compiler =
432434
Compiler { sess, codegen_backend, override_queries: config.override_queries };
433435

434-
rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || {
435-
// There are two paths out of `f`.
436-
// - Normal exit.
437-
// - Panic, e.g. triggered by `abort_if_errors`.
438-
//
439-
// We must run `finish_diagnostics` in both cases.
440-
let res = {
441-
// If `f` panics, `finish_diagnostics` will run during
442-
// unwinding because of the `defer`.
443-
let mut guar = None;
444-
let sess_abort_guard = defer(|| {
445-
guar = compiler.sess.finish_diagnostics(&config.registry);
446-
});
447-
448-
let res = f(&compiler);
449-
450-
// If `f` doesn't panic, `finish_diagnostics` will run
451-
// normally when `sess_abort_guard` is dropped.
452-
drop(sess_abort_guard);
453-
454-
// If `finish_diagnostics` emits errors (e.g. stashed
455-
// errors) we can't return an error directly, because the
456-
// return type of this function is `R`, not `Result<R, E>`.
457-
// But we need to communicate the errors' existence to the
458-
// caller, otherwise the caller might mistakenly think that
459-
// no errors occurred and return a zero exit code. So we
460-
// abort (panic) instead, similar to if `f` had panicked.
461-
if guar.is_some() {
462-
compiler.sess.dcx().abort_if_errors();
463-
}
436+
// There are two paths out of `f`.
437+
// - Normal exit.
438+
// - Panic, e.g. triggered by `abort_if_errors`.
439+
//
440+
// We must run `finish_diagnostics` in both cases.
441+
let res = {
442+
// If `f` panics, `finish_diagnostics` will run during
443+
// unwinding because of the `defer`.
444+
let mut guar = None;
445+
let sess_abort_guard = defer(|| {
446+
guar = compiler.sess.finish_diagnostics(&config.registry);
447+
});
448+
449+
let res = f(&compiler);
450+
451+
// If `f` doesn't panic, `finish_diagnostics` will run
452+
// normally when `sess_abort_guard` is dropped.
453+
drop(sess_abort_guard);
454+
455+
// If `finish_diagnostics` emits errors (e.g. stashed
456+
// errors) we can't return an error directly, because the
457+
// return type of this function is `R`, not `Result<R, E>`.
458+
// But we need to communicate the errors' existence to the
459+
// caller, otherwise the caller might mistakenly think that
460+
// no errors occurred and return a zero exit code. So we
461+
// abort (panic) instead, similar to if `f` had panicked.
462+
if guar.is_some() {
463+
compiler.sess.dcx().abort_if_errors();
464+
}
464465

465-
res
466-
};
466+
res
467+
};
467468

468-
let prof = compiler.sess.prof.clone();
469-
prof.generic_activity("drop_compiler").run(move || drop(compiler));
469+
let prof = compiler.sess.prof.clone();
470+
prof.generic_activity("drop_compiler").run(move || drop(compiler));
470471

471-
res
472-
})
472+
res
473473
},
474474
)
475475
}

compiler/rustc_interface/src/tests.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_session::search_paths::SearchPath;
1616
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
1717
use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session};
1818
use rustc_span::edition::{Edition, DEFAULT_EDITION};
19+
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
1920
use rustc_span::symbol::sym;
2021
use rustc_span::{FileName, SourceFileHashAlgorithm};
2122
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
@@ -36,15 +37,22 @@ where
3637
let sessopts = build_session_options(&mut early_dcx, &matches);
3738
let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());
3839
let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot);
40+
let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target);
41+
let sm_inputs = Some(SourceMapInputs {
42+
file_loader: Box::new(RealFileLoader) as _,
43+
path_mapping: sessopts.file_path_mapping(),
44+
hash_kind,
45+
});
3946

40-
rustc_span::create_default_session_globals_then(|| {
47+
rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || {
4148
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
4249
let io = CompilerIO {
4350
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
4451
output_dir: None,
4552
output_file: None,
4653
temps_dir,
4754
};
55+
4856
let sess = build_session(
4957
early_dcx,
5058
sessopts,
@@ -53,7 +61,6 @@ where
5361
registry::Registry::new(&[]),
5462
vec![],
5563
Default::default(),
56-
None,
5764
target,
5865
sysroot,
5966
"",

compiler/rustc_interface/src/util.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
1313
use rustc_session::{filesearch, Session};
1414
use rustc_span::edit_distance::find_best_match_for_name;
1515
use rustc_span::edition::Edition;
16+
use rustc_span::source_map::SourceMapInputs;
1617
use rustc_span::symbol::sym;
1718
use rustc_target::spec::Target;
1819
use session::output::{categorize_crate_type, CRATE_TYPES};
@@ -56,8 +57,9 @@ fn get_stack_size() -> Option<usize> {
5657
env::var_os("RUST_MIN_STACK").is_none().then_some(STACK_SIZE)
5758
}
5859

59-
pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>(
60+
fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>(
6061
edition: Edition,
62+
sm_inputs: SourceMapInputs,
6163
f: F,
6264
) -> R {
6365
// The "thread pool" is a single spawned thread in the non-parallel
@@ -77,7 +79,9 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>(
7779
// `unwrap` is ok here because `spawn_scoped` only panics if the thread
7880
// name contains null bytes.
7981
let r = builder
80-
.spawn_scoped(s, move || rustc_span::create_session_globals_then(edition, f))
82+
.spawn_scoped(s, move || {
83+
rustc_span::create_session_globals_then(edition, Some(sm_inputs), f)
84+
})
8185
.unwrap()
8286
.join();
8387

@@ -92,15 +96,17 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce() -> R + Send, R: Send>(
9296
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
9397
edition: Edition,
9498
_threads: usize,
99+
sm_inputs: SourceMapInputs,
95100
f: F,
96101
) -> R {
97-
run_in_thread_with_globals(edition, f)
102+
run_in_thread_with_globals(edition, sm_inputs, f)
98103
}
99104

100105
#[cfg(parallel_compiler)]
101106
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
102107
edition: Edition,
103108
threads: usize,
109+
sm_inputs: SourceMapInputs,
104110
f: F,
105111
) -> R {
106112
use rustc_data_structures::{defer, jobserver, sync::FromDyn};
@@ -112,7 +118,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
112118
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
113119

114120
if !sync::is_dyn_thread_safe() {
115-
return run_in_thread_with_globals(edition, || {
121+
return run_in_thread_with_globals(edition, sm_inputs, || {
116122
// Register the thread for use with the `WorkerLocal` type.
117123
registry.register();
118124

@@ -153,7 +159,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
153159
// pool. Upon creation, each worker thread created gets a copy of the
154160
// session globals in TLS. This is possible because `SessionGlobals` impls
155161
// `Send` in the parallel compiler.
156-
rustc_span::create_session_globals_then(edition, || {
162+
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
157163
rustc_span::with_session_globals(|session_globals| {
158164
let session_globals = FromDyn::from(session_globals);
159165
builder

compiler/rustc_log/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap();
1818
//!
1919
//! let edition = rustc_span::edition::Edition::Edition2021;
20-
//! rustc_span::create_session_globals_then(edition, || {
20+
//! rustc_span::create_session_globals_then(edition, None, || {
2121
//! /* ... */
2222
//! });
2323
//! }

compiler/rustc_session/src/config.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ impl Options {
10881088
|| self.unstable_opts.query_dep_graph
10891089
}
10901090

1091-
pub(crate) fn file_path_mapping(&self) -> FilePathMapping {
1091+
pub fn file_path_mapping(&self) -> FilePathMapping {
10921092
file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
10931093
}
10941094

@@ -1125,6 +1125,16 @@ impl UnstableOptions {
11251125
track_diagnostics: self.track_diagnostics,
11261126
}
11271127
}
1128+
1129+
pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1130+
self.src_hash_algorithm.unwrap_or_else(|| {
1131+
if target.is_like_msvc {
1132+
SourceFileHashAlgorithm::Sha256
1133+
} else {
1134+
SourceFileHashAlgorithm::Md5
1135+
}
1136+
})
1137+
}
11281138
}
11291139

11301140
// The type of entry function, so users can have their own entry functions

compiler/rustc_session/src/session.rs

+3-17
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use rustc_errors::{
2828
use rustc_macros::HashStable_Generic;
2929
pub use rustc_span::def_id::StableCrateId;
3030
use rustc_span::edition::Edition;
31-
use rustc_span::source_map::{FileLoader, FilePathMapping, RealFileLoader, SourceMap};
32-
use rustc_span::{SourceFileHashAlgorithm, Span, Symbol};
31+
use rustc_span::source_map::{FilePathMapping, SourceMap};
32+
use rustc_span::{Span, Symbol};
3333
use rustc_target::asm::InlineAsmArch;
3434
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
3535
use rustc_target::spec::{
@@ -1007,7 +1007,6 @@ pub fn build_session(
10071007
registry: rustc_errors::registry::Registry,
10081008
fluent_resources: Vec<&'static str>,
10091009
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
1010-
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
10111010
target: Target,
10121011
sysroot: PathBuf,
10131012
cfg_version: &'static str,
@@ -1034,24 +1033,11 @@ pub fn build_session(
10341033
early_dcx.early_warn(warning)
10351034
}
10361035

1037-
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
1038-
let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| {
1039-
if target.is_like_msvc {
1040-
SourceFileHashAlgorithm::Sha256
1041-
} else {
1042-
SourceFileHashAlgorithm::Md5
1043-
}
1044-
});
1045-
let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
1046-
loader,
1047-
sopts.file_path_mapping(),
1048-
hash_kind,
1049-
));
1050-
10511036
let fallback_bundle = fallback_fluent_bundle(
10521037
fluent_resources,
10531038
sopts.unstable_opts.translate_directionality_markers,
10541039
);
1040+
let source_map = rustc_span::source_map::get_source_map().unwrap();
10551041
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
10561042

10571043
let mut dcx =

0 commit comments

Comments
 (0)