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.
This commit is contained in:
parent
ff2e4ed1f1
commit
62c32aeeab
@ -14,7 +14,7 @@ fn def_path_hash_depends_on_crate_id() {
|
|||||||
// the crate by changing the crate disambiguator (e.g. via bumping the
|
// the crate by changing the crate disambiguator (e.g. via bumping the
|
||||||
// crate's version number).
|
// 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 id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], "");
|
||||||
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");
|
let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], "");
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
use rustc_session::filesearch::{self, sysroot_candidates};
|
use rustc_session::filesearch::{self, sysroot_candidates};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session};
|
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::symbol::sym;
|
||||||
use rustc_span::FileName;
|
use rustc_span::FileName;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -336,18 +336,23 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
|||||||
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
|
let early_dcx = EarlyDiagCtxt::new(config.opts.error_format);
|
||||||
early_dcx.initialize_checked_jobserver();
|
early_dcx.initialize_checked_jobserver();
|
||||||
|
|
||||||
|
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(
|
util::run_in_thread_pool_with_globals(
|
||||||
config.opts.edition,
|
config.opts.edition,
|
||||||
config.opts.unstable_opts.threads,
|
config.opts.unstable_opts.threads,
|
||||||
|
SourceMapInputs { file_loader, path_mapping, hash_kind },
|
||||||
|current_gcx| {
|
|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 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 {
|
let codegen_backend = match config.make_codegen_backend {
|
||||||
None => util::get_codegen_backend(
|
None => util::get_codegen_backend(
|
||||||
&early_dcx,
|
&early_dcx,
|
||||||
@ -372,9 +377,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
|||||||
config.opts.unstable_opts.translate_directionality_markers,
|
config.opts.unstable_opts.translate_directionality_markers,
|
||||||
) {
|
) {
|
||||||
Ok(bundle) => bundle,
|
Ok(bundle) => bundle,
|
||||||
Err(e) => {
|
Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
|
||||||
early_dcx.early_fatal(format!("failed to load fluent bundle: {e}"));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut locale_resources = Vec::from(config.locale_resources);
|
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
|
|||||||
config.registry.clone(),
|
config.registry.clone(),
|
||||||
locale_resources,
|
locale_resources,
|
||||||
config.lint_caps,
|
config.lint_caps,
|
||||||
config.file_loader,
|
|
||||||
target,
|
target,
|
||||||
sysroot,
|
sysroot,
|
||||||
util::rustc_version_str().unwrap_or("unknown"),
|
util::rustc_version_str().unwrap_or("unknown"),
|
||||||
@ -440,7 +442,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
|||||||
current_gcx,
|
current_gcx,
|
||||||
};
|
};
|
||||||
|
|
||||||
rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || {
|
|
||||||
// There are two paths out of `f`.
|
// There are two paths out of `f`.
|
||||||
// - Normal exit.
|
// - Normal exit.
|
||||||
// - Panic, e.g. triggered by `abort_if_errors`.
|
// - Panic, e.g. triggered by `abort_if_errors`.
|
||||||
@ -478,7 +479,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
|||||||
prof.generic_activity("drop_compiler").run(move || drop(compiler));
|
prof.generic_activity("drop_compiler").run(move || drop(compiler));
|
||||||
|
|
||||||
res
|
res
|
||||||
})
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
|
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
|
||||||
use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session};
|
use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session};
|
||||||
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
use rustc_span::edition::{Edition, DEFAULT_EDITION};
|
||||||
|
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{FileName, SourceFileHashAlgorithm};
|
use rustc_span::{FileName, SourceFileHashAlgorithm};
|
||||||
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
|
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
|
||||||
@ -36,8 +37,14 @@ fn sess_and_cfg<F>(args: &[&'static str], f: F)
|
|||||||
let sessopts = build_session_options(&mut early_dcx, &matches);
|
let sessopts = build_session_options(&mut early_dcx, &matches);
|
||||||
let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());
|
let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone());
|
||||||
let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot);
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
rustc_span::create_default_session_globals_then(|| {
|
rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || {
|
||||||
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
|
let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
|
||||||
let io = CompilerIO {
|
let io = CompilerIO {
|
||||||
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
|
input: Input::Str { name: FileName::Custom(String::new()), input: String::new() },
|
||||||
@ -45,6 +52,7 @@ fn sess_and_cfg<F>(args: &[&'static str], f: F)
|
|||||||
output_file: None,
|
output_file: None,
|
||||||
temps_dir,
|
temps_dir,
|
||||||
};
|
};
|
||||||
|
|
||||||
let sess = build_session(
|
let sess = build_session(
|
||||||
early_dcx,
|
early_dcx,
|
||||||
sessopts,
|
sessopts,
|
||||||
@ -53,7 +61,6 @@ fn sess_and_cfg<F>(args: &[&'static str], f: F)
|
|||||||
registry::Registry::new(&[]),
|
registry::Registry::new(&[]),
|
||||||
vec![],
|
vec![],
|
||||||
Default::default(),
|
Default::default(),
|
||||||
None,
|
|
||||||
target,
|
target,
|
||||||
sysroot,
|
sysroot,
|
||||||
"",
|
"",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
use rustc_session::{filesearch, Session};
|
use rustc_session::{filesearch, Session};
|
||||||
use rustc_span::edit_distance::find_best_match_for_name;
|
use rustc_span::edit_distance::find_best_match_for_name;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
|
use rustc_span::source_map::SourceMapInputs;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_target::spec::Target;
|
use rustc_target::spec::Target;
|
||||||
use session::output::{categorize_crate_type, CRATE_TYPES};
|
use session::output::{categorize_crate_type, CRATE_TYPES};
|
||||||
@ -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,
|
edition: Edition,
|
||||||
|
sm_inputs: SourceMapInputs,
|
||||||
f: F,
|
f: F,
|
||||||
) -> R {
|
) -> R {
|
||||||
// The "thread pool" is a single spawned thread in the non-parallel
|
// 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
|
|||||||
// name contains null bytes.
|
// name contains null bytes.
|
||||||
let r = builder
|
let r = builder
|
||||||
.spawn_scoped(s, move || {
|
.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()
|
.unwrap()
|
||||||
.join();
|
.join();
|
||||||
@ -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>(
|
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
|
||||||
edition: Edition,
|
edition: Edition,
|
||||||
_threads: usize,
|
_threads: usize,
|
||||||
|
sm_inputs: SourceMapInputs,
|
||||||
f: F,
|
f: F,
|
||||||
) -> R {
|
) -> R {
|
||||||
run_in_thread_with_globals(edition, f)
|
run_in_thread_with_globals(edition, sm_inputs, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
|
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
|
||||||
edition: Edition,
|
edition: Edition,
|
||||||
threads: usize,
|
threads: usize,
|
||||||
|
sm_inputs: SourceMapInputs,
|
||||||
f: F,
|
f: F,
|
||||||
) -> R {
|
) -> R {
|
||||||
use rustc_data_structures::{defer, jobserver, sync::FromDyn};
|
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,
|
|||||||
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
|
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
|
||||||
|
|
||||||
if !sync::is_dyn_thread_safe() {
|
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.
|
// Register the thread for use with the `WorkerLocal` type.
|
||||||
registry.register();
|
registry.register();
|
||||||
|
|
||||||
@ -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
|
// pool. Upon creation, each worker thread created gets a copy of the
|
||||||
// session globals in TLS. This is possible because `SessionGlobals` impls
|
// session globals in TLS. This is possible because `SessionGlobals` impls
|
||||||
// `Send` in the parallel compiler.
|
// `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| {
|
rustc_span::with_session_globals(|session_globals| {
|
||||||
let session_globals = FromDyn::from(session_globals);
|
let session_globals = FromDyn::from(session_globals);
|
||||||
builder
|
builder
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap();
|
//! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap();
|
||||||
//!
|
//!
|
||||||
//! let edition = rustc_span::edition::Edition::Edition2021;
|
//! let edition = rustc_span::edition::Edition::Edition2021;
|
||||||
//! rustc_span::create_session_globals_then(edition, || {
|
//! rustc_span::create_session_globals_then(edition, None, || {
|
||||||
//! /* ... */
|
//! /* ... */
|
||||||
//! });
|
//! });
|
||||||
//! }
|
//! }
|
||||||
|
@ -1125,7 +1125,7 @@ pub fn build_dep_graph(&self) -> bool {
|
|||||||
|| self.unstable_opts.query_dep_graph
|
|| self.unstable_opts.query_dep_graph
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn file_path_mapping(&self) -> FilePathMapping {
|
pub fn file_path_mapping(&self) -> FilePathMapping {
|
||||||
file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
|
file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,6 +1162,16 @@ pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
|
|||||||
track_diagnostics: self.track_diagnostics,
|
track_diagnostics: self.track_diagnostics,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
|
||||||
|
self.src_hash_algorithm.unwrap_or_else(|| {
|
||||||
|
if target.is_like_msvc {
|
||||||
|
SourceFileHashAlgorithm::Sha256
|
||||||
|
} else {
|
||||||
|
SourceFileHashAlgorithm::Md5
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The type of entry function, so users can have their own entry functions
|
// The type of entry function, so users can have their own entry functions
|
||||||
|
@ -28,9 +28,9 @@
|
|||||||
use rustc_macros::HashStable_Generic;
|
use rustc_macros::HashStable_Generic;
|
||||||
pub use rustc_span::def_id::StableCrateId;
|
pub use rustc_span::def_id::StableCrateId;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::source_map::{FileLoader, FilePathMapping, RealFileLoader, SourceMap};
|
use rustc_span::source_map::{FilePathMapping, SourceMap};
|
||||||
use rustc_span::{FileNameDisplayPreference, RealFileName};
|
use rustc_span::{FileNameDisplayPreference, RealFileName};
|
||||||
use rustc_span::{SourceFileHashAlgorithm, Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
use rustc_target::asm::InlineAsmArch;
|
use rustc_target::asm::InlineAsmArch;
|
||||||
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
|
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
|
||||||
use rustc_target::spec::{
|
use rustc_target::spec::{
|
||||||
@ -988,7 +988,6 @@ pub fn build_session(
|
|||||||
registry: rustc_errors::registry::Registry,
|
registry: rustc_errors::registry::Registry,
|
||||||
fluent_resources: Vec<&'static str>,
|
fluent_resources: Vec<&'static str>,
|
||||||
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||||
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
|
|
||||||
target: Target,
|
target: Target,
|
||||||
sysroot: PathBuf,
|
sysroot: PathBuf,
|
||||||
cfg_version: &'static str,
|
cfg_version: &'static str,
|
||||||
@ -1015,24 +1014,11 @@ pub fn build_session(
|
|||||||
early_dcx.early_warn(warning)
|
early_dcx.early_warn(warning)
|
||||||
}
|
}
|
||||||
|
|
||||||
let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
|
|
||||||
let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| {
|
|
||||||
if target.is_like_msvc {
|
|
||||||
SourceFileHashAlgorithm::Sha256
|
|
||||||
} else {
|
|
||||||
SourceFileHashAlgorithm::Md5
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind(
|
|
||||||
loader,
|
|
||||||
sopts.file_path_mapping(),
|
|
||||||
hash_kind,
|
|
||||||
));
|
|
||||||
|
|
||||||
let fallback_bundle = fallback_fluent_bundle(
|
let fallback_bundle = fallback_fluent_bundle(
|
||||||
fluent_resources,
|
fluent_resources,
|
||||||
sopts.unstable_opts.translate_directionality_markers,
|
sopts.unstable_opts.translate_directionality_markers,
|
||||||
);
|
);
|
||||||
|
let source_map = rustc_span::source_map::get_source_map().unwrap();
|
||||||
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
|
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
|
||||||
|
|
||||||
let mut dcx =
|
let mut dcx =
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
mod caching_source_map_view;
|
mod caching_source_map_view;
|
||||||
pub mod source_map;
|
pub mod source_map;
|
||||||
pub use self::caching_source_map_view::CachingSourceMapView;
|
pub use self::caching_source_map_view::CachingSourceMapView;
|
||||||
use source_map::SourceMap;
|
use source_map::{SourceMap, SourceMapInputs};
|
||||||
|
|
||||||
pub mod edition;
|
pub mod edition;
|
||||||
use edition::Edition;
|
use edition::Edition;
|
||||||
@ -104,35 +104,35 @@ pub struct SessionGlobals {
|
|||||||
metavar_spans: Lock<FxHashMap<Span, Span>>,
|
metavar_spans: Lock<FxHashMap<Span, Span>>,
|
||||||
hygiene_data: Lock<hygiene::HygieneData>,
|
hygiene_data: Lock<hygiene::HygieneData>,
|
||||||
|
|
||||||
/// A reference to the source map in the `Session`. It's an `Option`
|
/// The session's source map, if there is one. This field should only be
|
||||||
/// because it can't be initialized until `Session` is created, which
|
/// used in places where the `Session` is truly not available, such as
|
||||||
/// happens after `SessionGlobals`. `set_source_map` does the
|
/// `<Span as Debug>::fmt`.
|
||||||
/// initialization.
|
source_map: Option<Lrc<SourceMap>>,
|
||||||
///
|
|
||||||
/// This field should only be used in places where the `Session` is truly
|
|
||||||
/// not available, such as `<Span as Debug>::fmt`.
|
|
||||||
source_map: Lock<Option<Lrc<SourceMap>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SessionGlobals {
|
impl SessionGlobals {
|
||||||
pub fn new(edition: Edition) -> SessionGlobals {
|
pub fn new(edition: Edition, sm_inputs: Option<SourceMapInputs>) -> SessionGlobals {
|
||||||
SessionGlobals {
|
SessionGlobals {
|
||||||
symbol_interner: symbol::Interner::fresh(),
|
symbol_interner: symbol::Interner::fresh(),
|
||||||
span_interner: Lock::new(span_encoding::SpanInterner::default()),
|
span_interner: Lock::new(span_encoding::SpanInterner::default()),
|
||||||
metavar_spans: Default::default(),
|
metavar_spans: Default::default(),
|
||||||
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
|
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
|
||||||
source_map: Lock::new(None),
|
source_map: sm_inputs.map(|inputs| Lrc::new(SourceMap::with_inputs(inputs))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_session_globals_then<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
|
pub fn create_session_globals_then<R>(
|
||||||
|
edition: Edition,
|
||||||
|
sm_inputs: Option<SourceMapInputs>,
|
||||||
|
f: impl FnOnce() -> R,
|
||||||
|
) -> R {
|
||||||
assert!(
|
assert!(
|
||||||
!SESSION_GLOBALS.is_set(),
|
!SESSION_GLOBALS.is_set(),
|
||||||
"SESSION_GLOBALS should never be overwritten! \
|
"SESSION_GLOBALS should never be overwritten! \
|
||||||
Use another thread if you need another SessionGlobals"
|
Use another thread if you need another SessionGlobals"
|
||||||
);
|
);
|
||||||
let session_globals = SessionGlobals::new(edition);
|
let session_globals = SessionGlobals::new(edition, sm_inputs);
|
||||||
SESSION_GLOBALS.set(&session_globals, f)
|
SESSION_GLOBALS.set(&session_globals, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,12 +145,13 @@ pub fn set_session_globals_then<R>(session_globals: &SessionGlobals, f: impl FnO
|
|||||||
SESSION_GLOBALS.set(session_globals, f)
|
SESSION_GLOBALS.set(session_globals, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// No source map.
|
||||||
pub fn create_session_if_not_set_then<R, F>(edition: Edition, f: F) -> R
|
pub fn create_session_if_not_set_then<R, F>(edition: Edition, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&SessionGlobals) -> R,
|
F: FnOnce(&SessionGlobals) -> R,
|
||||||
{
|
{
|
||||||
if !SESSION_GLOBALS.is_set() {
|
if !SESSION_GLOBALS.is_set() {
|
||||||
let session_globals = SessionGlobals::new(edition);
|
let session_globals = SessionGlobals::new(edition, None);
|
||||||
SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f))
|
SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f))
|
||||||
} else {
|
} else {
|
||||||
SESSION_GLOBALS.with(f)
|
SESSION_GLOBALS.with(f)
|
||||||
@ -164,8 +165,9 @@ pub fn with_session_globals<R, F>(f: F) -> R
|
|||||||
SESSION_GLOBALS.with(f)
|
SESSION_GLOBALS.with(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Default edition, no source map.
|
||||||
pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
|
pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
|
||||||
create_session_globals_then(edition::DEFAULT_EDITION, f)
|
create_session_globals_then(edition::DEFAULT_EDITION, None, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this ever becomes non thread-local, `decode_syntax_context`
|
// If this ever becomes non thread-local, `decode_syntax_context`
|
||||||
@ -1318,25 +1320,6 @@ fn decode(s: &mut D) -> AttrId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert `source_map` into the session globals for the duration of the
|
|
||||||
/// closure's execution.
|
|
||||||
pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
|
|
||||||
with_session_globals(|session_globals| {
|
|
||||||
*session_globals.source_map.borrow_mut() = Some(source_map);
|
|
||||||
});
|
|
||||||
struct ClearSourceMap;
|
|
||||||
impl Drop for ClearSourceMap {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
with_session_globals(|session_globals| {
|
|
||||||
session_globals.source_map.borrow_mut().take();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let _guard = ClearSourceMap;
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for Span {
|
impl fmt::Debug for Span {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
// Use the global `SourceMap` to print the span. If that's not
|
// Use the global `SourceMap` to print the span. If that's not
|
||||||
@ -1352,7 +1335,7 @@ fn fallback(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
|
|
||||||
if SESSION_GLOBALS.is_set() {
|
if SESSION_GLOBALS.is_set() {
|
||||||
with_session_globals(|session_globals| {
|
with_session_globals(|session_globals| {
|
||||||
if let Some(source_map) = &*session_globals.source_map.borrow() {
|
if let Some(source_map) = &session_globals.source_map {
|
||||||
write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
|
write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
|
||||||
} else {
|
} else {
|
||||||
fallback(*self, f)
|
fallback(*self, f)
|
||||||
|
@ -167,9 +167,17 @@ struct SourceMapFiles {
|
|||||||
stable_id_to_source_file: UnhashMap<StableSourceFileId, Lrc<SourceFile>>,
|
stable_id_to_source_file: UnhashMap<StableSourceFileId, Lrc<SourceFile>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to construct a `SourceMap` with `SourceMap::with_inputs`.
|
||||||
|
pub struct SourceMapInputs {
|
||||||
|
pub file_loader: Box<dyn FileLoader + Send + Sync>,
|
||||||
|
pub path_mapping: FilePathMapping,
|
||||||
|
pub hash_kind: SourceFileHashAlgorithm,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SourceMap {
|
pub struct SourceMap {
|
||||||
files: RwLock<SourceMapFiles>,
|
files: RwLock<SourceMapFiles>,
|
||||||
file_loader: IntoDynSyncSend<Box<dyn FileLoader + Sync + Send>>,
|
file_loader: IntoDynSyncSend<Box<dyn FileLoader + Sync + Send>>,
|
||||||
|
|
||||||
// This is used to apply the file path remapping as specified via
|
// This is used to apply the file path remapping as specified via
|
||||||
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
|
// `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
|
||||||
path_mapping: FilePathMapping,
|
path_mapping: FilePathMapping,
|
||||||
@ -180,17 +188,15 @@ pub struct SourceMap {
|
|||||||
|
|
||||||
impl SourceMap {
|
impl SourceMap {
|
||||||
pub fn new(path_mapping: FilePathMapping) -> SourceMap {
|
pub fn new(path_mapping: FilePathMapping) -> SourceMap {
|
||||||
Self::with_file_loader_and_hash_kind(
|
Self::with_inputs(SourceMapInputs {
|
||||||
Box::new(RealFileLoader),
|
file_loader: Box::new(RealFileLoader),
|
||||||
path_mapping,
|
path_mapping,
|
||||||
SourceFileHashAlgorithm::Md5,
|
hash_kind: SourceFileHashAlgorithm::Md5,
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_file_loader_and_hash_kind(
|
pub fn with_inputs(
|
||||||
file_loader: Box<dyn FileLoader + Sync + Send>,
|
SourceMapInputs { file_loader, path_mapping, hash_kind }: SourceMapInputs,
|
||||||
path_mapping: FilePathMapping,
|
|
||||||
hash_kind: SourceFileHashAlgorithm,
|
|
||||||
) -> SourceMap {
|
) -> SourceMap {
|
||||||
SourceMap {
|
SourceMap {
|
||||||
files: Default::default(),
|
files: Default::default(),
|
||||||
@ -1054,6 +1060,10 @@ pub fn mac_call_stmt_semi_span(&self, mac_call: Span) -> Option<Span> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_source_map() -> Option<Lrc<SourceMap>> {
|
||||||
|
with_session_globals(|session_globals| session_globals.source_map.clone())
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FilePathMapping {
|
pub struct FilePathMapping {
|
||||||
mapping: Vec<(PathBuf, PathBuf)>,
|
mapping: Vec<(PathBuf, PathBuf)>,
|
||||||
|
@ -38,7 +38,7 @@ pub fn check(
|
|||||||
// of all `#[test]` attributes in not ignored code examples
|
// of all `#[test]` attributes in not ignored code examples
|
||||||
fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) {
|
fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) {
|
||||||
rustc_driver::catch_fatal_errors(|| {
|
rustc_driver::catch_fatal_errors(|| {
|
||||||
rustc_span::create_session_globals_then(edition, || {
|
rustc_span::create_session_globals_then(edition, None, || {
|
||||||
let mut test_attr_spans = vec![];
|
let mut test_attr_spans = vec![];
|
||||||
let filename = FileName::anon_source_code(&code);
|
let filename = FileName::anon_source_code(&code);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user