Skip to content

Commit 6279571

Browse files
committed
Auto merge of #72618 - Aaron1011:feature/early-sourcemap, r=petrochenkov
Make `SourceMap` available for early debug-printing of `Span`s Normally, we debug-print `Spans` using the `SourceMap` retrieved from the global `TyCtxt`. However, we fall back to printing out the `Span`'s raw fields (instead of a file and line number) when we try to print a `Span` before a `TyCtxt` is available. This makes debugging early phases of the compile, such as parsing, much more difficult. This commit stores a `SourceMap` in `rustc_span::GlOBALS` as a fallback. When a `TyCtxt` is not available, we try to retrieve one from `GLOBALS` - only if this is not available do we fall back to the raw field output. I'm not sure how to write a test for this - however, this can be verified locally by setting `RUSTC_LOG="rustc_parse=debug"`, and verifying that the output contains filenames and line numbers.
2 parents f3fadf6 + 717fd66 commit 6279571

File tree

2 files changed

+53
-16
lines changed

2 files changed

+53
-16
lines changed

src/librustc_interface/interface.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,19 @@ pub fn run_compiler_in_existing_thread_pool<R>(
186186
override_queries: config.override_queries,
187187
};
188188

189-
let r = {
190-
let _sess_abort_error = OnDrop(|| {
191-
compiler.sess.finish_diagnostics(registry);
192-
});
193-
194-
f(&compiler)
195-
};
196-
197-
let prof = compiler.sess.prof.clone();
198-
prof.generic_activity("drop_compiler").run(move || drop(compiler));
199-
r
189+
rustc_span::with_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
190+
let r = {
191+
let _sess_abort_error = OnDrop(|| {
192+
compiler.sess.finish_diagnostics(registry);
193+
});
194+
195+
f(&compiler)
196+
};
197+
198+
let prof = compiler.sess.prof.clone();
199+
prof.generic_activity("drop_compiler").run(move || drop(compiler));
200+
r
201+
})
200202
}
201203

202204
pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {

src/librustc_span/lib.rs

+40-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
2525
mod caching_source_map_view;
2626
pub mod source_map;
2727
pub use self::caching_source_map_view::CachingSourceMapView;
28+
use source_map::SourceMap;
2829

2930
pub mod edition;
3031
use edition::Edition;
@@ -67,6 +68,7 @@ pub struct Globals {
6768
symbol_interner: Lock<symbol::Interner>,
6869
span_interner: Lock<span_encoding::SpanInterner>,
6970
hygiene_data: Lock<hygiene::HygieneData>,
71+
source_map: Lock<Option<Lrc<SourceMap>>>,
7072
}
7173

7274
impl Globals {
@@ -75,6 +77,7 @@ impl Globals {
7577
symbol_interner: Lock::new(symbol::Interner::fresh()),
7678
span_interner: Lock::new(span_encoding::SpanInterner::default()),
7779
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
80+
source_map: Lock::new(None),
7881
}
7982
}
8083
}
@@ -697,12 +700,44 @@ impl rustc_serialize::UseSpecializedDecodable for Span {
697700
}
698701
}
699702

703+
/// Calls the provided closure, using the provided `SourceMap` to format
704+
/// any spans that are debug-printed during the closure'e exectuino.
705+
///
706+
/// Normally, the global `TyCtxt` is used to retrieve the `SourceMap`
707+
/// (see `rustc_interface::callbacks::span_debug1). However, some parts
708+
/// of the compiler (e.g. `rustc_parse`) may debug-print `Span`s before
709+
/// a `TyCtxt` is available. In this case, we fall back to
710+
/// the `SourceMap` provided to this function. If that is not available,
711+
/// we fall back to printing the raw `Span` field values
712+
pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
713+
GLOBALS.with(|globals| {
714+
*globals.source_map.borrow_mut() = Some(source_map);
715+
});
716+
struct ClearSourceMap;
717+
impl Drop for ClearSourceMap {
718+
fn drop(&mut self) {
719+
GLOBALS.with(|globals| {
720+
globals.source_map.borrow_mut().take();
721+
});
722+
}
723+
}
724+
725+
let _guard = ClearSourceMap;
726+
f()
727+
}
728+
700729
pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
701-
f.debug_struct("Span")
702-
.field("lo", &span.lo())
703-
.field("hi", &span.hi())
704-
.field("ctxt", &span.ctxt())
705-
.finish()
730+
GLOBALS.with(|globals| {
731+
if let Some(source_map) = &*globals.source_map.borrow() {
732+
write!(f, "{}", source_map.span_to_string(span))
733+
} else {
734+
f.debug_struct("Span")
735+
.field("lo", &span.lo())
736+
.field("hi", &span.hi())
737+
.field("ctxt", &span.ctxt())
738+
.finish()
739+
}
740+
})
706741
}
707742

708743
impl fmt::Debug for Span {

0 commit comments

Comments
 (0)