diff --git a/src/librustc_middle/ich/hcx.rs b/src/librustc_middle/ich/hcx.rs index 19a7d2ec2218d..d047fa74075e7 100644 --- a/src/librustc_middle/ich/hcx.rs +++ b/src/librustc_middle/ich/hcx.rs @@ -226,6 +226,9 @@ impl<'a> HashStable> for ast::NodeId { } impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { + fn session_globals(&self) -> &rustc_span::SessionGlobals { + &self.sess.parse_sess.span_globals + } fn hash_spans(&self) -> bool { self.hash_spans } diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 9cdb7e966fef8..68e41c4c94501 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -11,7 +11,7 @@ use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{FilePathMapping, SourceMap}; -use rustc_span::{MultiSpan, Span, Symbol}; +use rustc_span::{MultiSpan, Span, Symbol, SessionGlobals}; use std::collections::BTreeMap; use std::path::PathBuf; @@ -140,6 +140,7 @@ pub struct ParseSess { pub env_depinfo: Lock)>>, /// All the type ascriptions expressions that have had a suggestion for likely path typo. pub type_ascription_path_suggestions: Lock>, + pub span_globals: Lrc } impl ParseSess { @@ -150,6 +151,7 @@ impl ParseSess { } pub fn with_span_handler(handler: Handler, source_map: Lrc) -> Self { + let span_globals = rustc_span::SESSION_GLOBALS.with(|g| g.clone()); Self { span_diagnostic: handler, unstable_features: UnstableFeatures::from_environment(), @@ -167,6 +169,7 @@ impl ParseSess { reached_eof: Lock::new(false), env_depinfo: Default::default(), type_ascription_path_suggestions: Default::default(), + span_globals } } diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 4c441e1cc71f5..b0b2ff9c645a0 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -88,7 +88,7 @@ impl SessionGlobals { } pub fn with_session_globals(edition: Edition, f: impl FnOnce() -> R) -> R { - let session_globals = SessionGlobals::new(edition); + let session_globals = Lrc::new(SessionGlobals::new(edition)); SESSION_GLOBALS.set(&session_globals, f) } @@ -99,7 +99,7 @@ pub fn with_default_session_globals(f: impl FnOnce() -> R) -> R { // If this ever becomes non thread-local, `decode_syntax_context` // and `decode_expn_id` will need to be updated to handle concurrent // deserialization. -scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals); +scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: Lrc); // FIXME: Perhaps this should not implement Rustc{Decodable, Encodable} // @@ -1746,6 +1746,7 @@ fn lookup_line(lines: &[BytePos], pos: BytePos) -> isize { /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in librustc_middle. pub trait HashStableContext { + fn session_globals(&self) -> &SessionGlobals; fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher); fn hash_crate_num(&mut self, _: CrateNum, hasher: &mut StableHasher); fn hash_spans(&self) -> bool; @@ -1781,10 +1782,12 @@ where return; } + let globals = ctx.session_globals(); + // If this is not an empty or invalid span, we want to hash the last // position that belongs to it, as opposed to hashing the first // position past it. - let span = self.data(); + let span = self.data_from_globals(globals); let (file_lo, line_lo, col_lo) = match ctx.byte_pos_to_line_and_col(span.lo) { Some(pos) => pos, None => { diff --git a/src/librustc_span/span_encoding.rs b/src/librustc_span/span_encoding.rs index 6b672d344fa51..02edf708cabaf 100644 --- a/src/librustc_span/span_encoding.rs +++ b/src/librustc_span/span_encoding.rs @@ -6,7 +6,7 @@ use crate::hygiene::SyntaxContext; use crate::SESSION_GLOBALS; -use crate::{BytePos, SpanData}; +use crate::{BytePos, SpanData, SessionGlobals}; use rustc_data_structures::fx::FxHashMap; @@ -92,6 +92,16 @@ impl Span { #[inline] pub fn data(self) -> SpanData { + self.data_with_interner(|index| with_span_interner(|interner| *interner.get(index))) + } + + #[inline] + pub fn data_from_globals(self, globals: &SessionGlobals) -> SpanData { + self.data_with_interner(|index| *globals.span_interner.lock().get(index)) + } + + #[inline] + pub fn data_with_interner(self, interner_get: impl FnOnce(u32) -> SpanData) -> SpanData { if self.len_or_tag != LEN_TAG { // Inline format. debug_assert!(self.len_or_tag as u32 <= MAX_LEN); @@ -104,7 +114,7 @@ impl Span { // Interned format. debug_assert!(self.ctxt_or_zero == 0); let index = self.base_or_index; - with_span_interner(|interner| *interner.get(index)) + interner_get(index) } } }