Skip to content

Commit 62c32ae

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.
1 parent ff2e4ed commit 62c32ae

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
@@ -21,7 +21,7 @@ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileN
2121
use rustc_session::filesearch::{self, sysroot_candidates};
2222
use rustc_session::parse::ParseSess;
2323
use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
24-
use rustc_span::source_map::FileLoader;
24+
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
2525
use rustc_span::symbol::sym;
2626
use rustc_span::FileName;
2727
use std::path::PathBuf;
@@ -336,18 +336,23 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
336336
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
337337
early_dcx.initialize_checked_jobserver();
338338

339+
crate::callbacks::setup_callbacks();
340+
341+
let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
342+
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);
343+
let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
344+
let path_mapping = config.opts.file_path_mapping();
345+
let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target);
346+
339347
util::run_in_thread_pool_with_globals(
340348
config.opts.edition,
341349
config.opts.unstable_opts.threads,
350+
SourceMapInputs { file_loader, path_mapping, hash_kind },
342351
|current_gcx| {
343-
crate::callbacks::setup_callbacks();
344-
352+
// The previous `early_dcx` can't be reused here because it doesn't
353+
// impl `Send`. Creating a new one is fine.
345354
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
346355

347-
let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone());
348-
349-
let target = config::build_target_config(&early_dcx, &config.opts, &sysroot);
350-
351356
let codegen_backend = match config.make_codegen_backend {
352357
None => util::get_codegen_backend(
353358
&early_dcx,
@@ -372,9 +377,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
372377
config.opts.unstable_opts.translate_directionality_markers,
373378
) {
374379
Ok(bundle) => bundle,
375-
Err(e) => {
376-
early_dcx.early_fatal(format!("failed to load fluent bundle: {e}"));
377-
}
380+
Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
378381
};
379382

380383
let mut locale_resources = Vec::from(config.locale_resources);
@@ -393,7 +396,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
393396
config.registry.clone(),
394397
locale_resources,
395398
config.lint_caps,
396-
config.file_loader,
397399
target,
398400
sysroot,
399401
util::rustc_version_str().unwrap_or("unknown"),
@@ -440,45 +442,43 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
440442
current_gcx,
441443
};
442444

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

474-
res
475-
};
475+
res
476+
};
476477

477-
let prof = compiler.sess.prof.clone();
478-
prof.generic_activity("drop_compiler").run(move || drop(compiler));
478+
let prof = compiler.sess.prof.clone();
479+
prof.generic_activity("drop_compiler").run(move || drop(compiler));
479480

480-
res
481-
})
481+
res
482482
},
483483
)
484484
}

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
@@ -14,6 +14,7 @@ use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
1414
use rustc_session::{filesearch, Session};
1515
use rustc_span::edit_distance::find_best_match_for_name;
1616
use rustc_span::edition::Edition;
17+
use rustc_span::source_map::SourceMapInputs;
1718
use rustc_span::symbol::sym;
1819
use rustc_target::spec::Target;
1920
use session::output::{categorize_crate_type, CRATE_TYPES};
@@ -65,8 +66,9 @@ fn init_stack_size() -> usize {
6566
})
6667
}
6768

68-
pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
69+
fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
6970
edition: Edition,
71+
sm_inputs: SourceMapInputs,
7072
f: F,
7173
) -> R {
7274
// The "thread pool" is a single spawned thread in the non-parallel
@@ -84,7 +86,9 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: S
8486
// name contains null bytes.
8587
let r = builder
8688
.spawn_scoped(s, move || {
87-
rustc_span::create_session_globals_then(edition, || f(CurrentGcx::new()))
89+
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
90+
f(CurrentGcx::new())
91+
})
8892
})
8993
.unwrap()
9094
.join();
@@ -100,15 +104,17 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: S
100104
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
101105
edition: Edition,
102106
_threads: usize,
107+
sm_inputs: SourceMapInputs,
103108
f: F,
104109
) -> R {
105-
run_in_thread_with_globals(edition, f)
110+
run_in_thread_with_globals(edition, sm_inputs, f)
106111
}
107112

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

122128
if !sync::is_dyn_thread_safe() {
123-
return run_in_thread_with_globals(edition, |current_gcx| {
129+
return run_in_thread_with_globals(edition, sm_inputs, |current_gcx| {
124130
// Register the thread for use with the `WorkerLocal` type.
125131
registry.register();
126132

@@ -169,7 +175,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
169175
// pool. Upon creation, each worker thread created gets a copy of the
170176
// session globals in TLS. This is possible because `SessionGlobals` impls
171177
// `Send` in the parallel compiler.
172-
rustc_span::create_session_globals_then(edition, || {
178+
rustc_span::create_session_globals_then(edition, Some(sm_inputs), || {
173179
rustc_span::with_session_globals(|session_globals| {
174180
let session_globals = FromDyn::from(session_globals);
175181
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
@@ -1125,7 +1125,7 @@ impl Options {
11251125
|| self.unstable_opts.query_dep_graph
11261126
}
11271127

1128-
pub(crate) fn file_path_mapping(&self) -> FilePathMapping {
1128+
pub fn file_path_mapping(&self) -> FilePathMapping {
11291129
file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
11301130
}
11311131

@@ -1162,6 +1162,16 @@ impl UnstableOptions {
11621162
track_diagnostics: self.track_diagnostics,
11631163
}
11641164
}
1165+
1166+
pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1167+
self.src_hash_algorithm.unwrap_or_else(|| {
1168+
if target.is_like_msvc {
1169+
SourceFileHashAlgorithm::Sha256
1170+
} else {
1171+
SourceFileHashAlgorithm::Md5
1172+
}
1173+
})
1174+
}
11651175
}
11661176

11671177
// 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,9 +28,9 @@ 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};
31+
use rustc_span::source_map::{FilePathMapping, SourceMap};
3232
use rustc_span::{FileNameDisplayPreference, RealFileName};
33-
use rustc_span::{SourceFileHashAlgorithm, Span, Symbol};
33+
use rustc_span::{Span, Symbol};
3434
use rustc_target::asm::InlineAsmArch;
3535
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
3636
use rustc_target::spec::{
@@ -988,7 +988,6 @@ pub fn build_session(
988988
registry: rustc_errors::registry::Registry,
989989
fluent_resources: Vec<&'static str>,
990990
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
991-
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
992991
target: Target,
993992
sysroot: PathBuf,
994993
cfg_version: &'static str,
@@ -1015,24 +1014,11 @@ pub fn build_session(
10151014
early_dcx.early_warn(warning)
10161015
}
10171016

1018-
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
1019-
let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| {
1020-
if target.is_like_msvc {
1021-
SourceFileHashAlgorithm::Sha256
1022-
} else {
1023-
SourceFileHashAlgorithm::Md5
1024-
}
1025-
});
1026-
let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
1027-
loader,
1028-
sopts.file_path_mapping(),
1029-
hash_kind,
1030-
));
1031-
10321017
let fallback_bundle = fallback_fluent_bundle(
10331018
fluent_resources,
10341019
sopts.unstable_opts.translate_directionality_markers,
10351020
);
1021+
let source_map = rustc_span::source_map::get_source_map().unwrap();
10361022
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
10371023

10381024
let mut dcx =

0 commit comments

Comments
 (0)