1
Fork 0

Rework SESSION_GLOBALS API to prevent overwriting it

This commit is contained in:
Guillaume Gomez 2021-05-05 21:31:25 +02:00 committed by Guillaume Gomez
parent 0cd0709f19
commit a2654fb64c
27 changed files with 146 additions and 100 deletions

View file

@ -26,7 +26,7 @@
use crate::edition::Edition;
use crate::symbol::{kw, sym, Symbol};
use crate::SESSION_GLOBALS;
use crate::with_session_globals;
use crate::{BytePos, CachingSourceMapView, ExpnIdCache, SourceFile, Span, DUMMY_SP};
use crate::def_id::{CrateNum, DefId, DefPathHash, CRATE_DEF_INDEX, LOCAL_CRATE};
@ -201,7 +201,7 @@ impl HygieneData {
}
pub fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut()))
with_session_globals(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut()))
}
fn fresh_expn(&mut self, mut expn_data: Option<ExpnData>) -> ExpnId {
@ -1367,8 +1367,9 @@ fn update_disambiguator(expn_id: ExpnId) {
}
}
let source_map = SESSION_GLOBALS
.with(|session_globals| session_globals.source_map.borrow().as_ref().unwrap().clone());
let source_map = with_session_globals(|session_globals| {
session_globals.source_map.borrow().as_ref().unwrap().clone()
});
let mut ctx =
DummyHashStableContext { caching_source_map: CachingSourceMapView::new(&source_map) };

View file

@ -21,8 +21,8 @@ fn test_lev_distance() {
#[test]
fn test_find_best_match_for_name() {
use crate::with_default_session_globals;
with_default_session_globals(|| {
use crate::create_default_session_globals_then;
create_default_session_globals_then(|| {
let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")];
assert_eq!(
find_best_match_for_name(&input, Symbol::intern("aaaa"), None),

View file

@ -97,19 +97,65 @@ impl SessionGlobals {
}
}
pub fn with_session_globals<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
#[inline]
pub fn create_session_globals_then<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
assert!(
!SESSION_GLOBALS.is_set(),
"SESSION_GLOBALS should never be overwritten! \
Use another thread if you need another SessionGlobals"
);
let session_globals = SessionGlobals::new(edition);
SESSION_GLOBALS.set(&session_globals, f)
}
pub fn with_default_session_globals<R>(f: impl FnOnce() -> R) -> R {
with_session_globals(edition::DEFAULT_EDITION, f)
#[inline]
pub fn set_session_globals_then<R>(session_globals: &SessionGlobals, f: impl FnOnce() -> R) -> R {
assert!(
!SESSION_GLOBALS.is_set(),
"SESSION_GLOBALS should never be overwritten! \
Use another thread if you need another SessionGlobals"
);
SESSION_GLOBALS.set(session_globals, f)
}
#[inline]
pub fn create_default_session_if_not_set_then<R, F>(f: F) -> R
where
F: FnOnce(&SessionGlobals) -> R,
{
create_session_if_not_set_then(edition::DEFAULT_EDITION, f)
}
#[inline]
pub fn create_session_if_not_set_then<R, F>(edition: Edition, f: F) -> R
where
F: FnOnce(&SessionGlobals) -> R,
{
if !SESSION_GLOBALS.is_set() {
let session_globals = SessionGlobals::new(edition);
SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f))
} else {
SESSION_GLOBALS.with(f)
}
}
#[inline]
pub fn with_session_globals<R, F>(f: F) -> R
where
F: FnOnce(&SessionGlobals) -> R,
{
SESSION_GLOBALS.with(f)
}
#[inline]
pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
create_session_globals_then(edition::DEFAULT_EDITION, f)
}
// 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!(static SESSION_GLOBALS: SessionGlobals);
// FIXME: We should use this enum or something like it to get rid of the
// use of magic `/rust/1.x/...` paths across the board.
@ -855,13 +901,13 @@ impl<D: Decoder> Decodable<D> for Span {
/// the `SourceMap` provided to this function. If that is not available,
/// we fall back to printing the raw `Span` field values.
pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
SESSION_GLOBALS.with(|session_globals| {
with_session_globals(|session_globals| {
*session_globals.source_map.borrow_mut() = Some(source_map);
});
struct ClearSourceMap;
impl Drop for ClearSourceMap {
fn drop(&mut self) {
SESSION_GLOBALS.with(|session_globals| {
with_session_globals(|session_globals| {
session_globals.source_map.borrow_mut().take();
});
}
@ -880,7 +926,7 @@ pub fn debug_with_source_map(
}
pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
SESSION_GLOBALS.with(|session_globals| {
with_session_globals(|session_globals| {
if let Some(source_map) = &*session_globals.source_map.borrow() {
debug_with_source_map(span, f, source_map)
} else {

View file

@ -5,7 +5,6 @@
// See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28
use crate::hygiene::SyntaxContext;
use crate::SESSION_GLOBALS;
use crate::{BytePos, SpanData};
use rustc_data_structures::fx::FxIndexSet;
@ -122,5 +121,5 @@ impl SpanInterner {
// If an interner exists, return it. Otherwise, prepare a fresh one.
#[inline]
fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.span_interner.lock()))
crate::with_session_globals(|session_globals| f(&mut *session_globals.span_interner.lock()))
}

View file

@ -13,7 +13,7 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::str;
use crate::{Edition, Span, DUMMY_SP, SESSION_GLOBALS};
use crate::{with_session_globals, Edition, Span, DUMMY_SP};
#[cfg(test)]
mod tests;
@ -1790,7 +1790,7 @@ impl Ident {
#[inline]
fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
with_session_globals(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
}
/// An alternative to [`Symbol`], useful when the chars within the symbol need to

View file

@ -1,6 +1,6 @@
use super::*;
use crate::{edition, SessionGlobals};
use crate::create_default_session_globals_then;
#[test]
fn interner_tests() {
@ -18,7 +18,7 @@ fn interner_tests() {
#[test]
fn without_first_quote_test() {
SESSION_GLOBALS.set(&SessionGlobals::new(edition::DEFAULT_EDITION), || {
create_default_session_globals_then(|| {
let i = Ident::from_str("'break");
assert_eq!(i.without_first_quote().name, kw::Break);
});