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<StableHashingContext<'a>> 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<FxHashSet<(Symbol, Option<Symbol>)>>,
     /// All the type ascriptions expressions that have had a suggestion for likely path typo.
     pub type_ascription_path_suggestions: Lock<FxHashSet<Span>>,
+    pub span_globals: Lrc<SessionGlobals>
 }
 
 impl ParseSess {
@@ -150,6 +151,7 @@ impl ParseSess {
     }
 
     pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> 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<R>(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<R>(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<SessionGlobals>);
 
 // 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)
         }
     }
 }