about summary refs log tree commit diff
path: root/src/libsyntax_pos
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-03-07 02:44:10 +0100
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-03-14 11:56:01 +0100
commitcbdf4ec03e92ed36c162bb8c645993e48a1caa02 (patch)
treed376a0ad7031e5cc10922957eb1575d7e0036b7d /src/libsyntax_pos
parentfab632f9759af4f3d96c6ec69e24e5428060dba4 (diff)
downloadrust-cbdf4ec03e92ed36c162bb8c645993e48a1caa02.tar.gz
rust-cbdf4ec03e92ed36c162bb8c645993e48a1caa02.zip
Remove syntax and syntax_pos thread locals
Diffstat (limited to 'src/libsyntax_pos')
-rw-r--r--src/libsyntax_pos/Cargo.toml1
-rw-r--r--src/libsyntax_pos/hygiene.rs11
-rw-r--r--src/libsyntax_pos/lib.rs23
-rw-r--r--src/libsyntax_pos/span_encoding.rs11
-rw-r--r--src/libsyntax_pos/symbol.rs19
5 files changed, 41 insertions, 24 deletions
diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml
index aad2155157d..b9637b1855e 100644
--- a/src/libsyntax_pos/Cargo.toml
+++ b/src/libsyntax_pos/Cargo.toml
@@ -11,4 +11,5 @@ crate-type = ["dylib"]
 [dependencies]
 serialize = { path = "../libserialize" }
 rustc_data_structures = { path = "../librustc_data_structures" }
+scoped-tls = { version = "0.1.1", features = ["nightly"] }
 unicode-width = "0.1.4"
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index b7fba9fe8df..85a2940ec44 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -15,11 +15,11 @@
 //! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216.
 //! DOI=10.1017/S0956796812000093 <http://dx.doi.org/10.1017/S0956796812000093>
 
+use GLOBALS;
 use Span;
 use symbol::{Ident, Symbol};
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
-use std::cell::RefCell;
 use std::collections::HashMap;
 use std::fmt;
 
@@ -119,7 +119,7 @@ impl Mark {
     }
 }
 
-struct HygieneData {
+pub struct HygieneData {
     marks: Vec<MarkData>,
     syntax_contexts: Vec<SyntaxContextData>,
     markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
@@ -127,7 +127,7 @@ struct HygieneData {
 }
 
 impl HygieneData {
-    fn new() -> Self {
+    pub fn new() -> Self {
         HygieneData {
             marks: vec![MarkData {
                 parent: Mark::root(),
@@ -145,10 +145,7 @@ impl HygieneData {
     }
 
     fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
-        thread_local! {
-            static HYGIENE_DATA: RefCell<HygieneData> = RefCell::new(HygieneData::new());
-        }
-        HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut()))
+        GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
     }
 }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index ed9eb5d5c92..bec46ff3d79 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -35,10 +35,13 @@ use std::ops::{Add, Sub};
 use std::path::PathBuf;
 
 use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, Lock};
 
 extern crate rustc_data_structures;
 
+#[macro_use]
+extern crate scoped_tls;
+
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 extern crate serialize;
@@ -54,6 +57,24 @@ pub use span_encoding::{Span, DUMMY_SP};
 
 pub mod symbol;
 
+pub struct Globals {
+    symbol_interner: Lock<symbol::Interner>,
+    span_interner: Lock<span_encoding::SpanInterner>,
+    hygiene_data: Lock<hygiene::HygieneData>,
+}
+
+impl Globals {
+    pub fn new() -> Globals {
+        Globals {
+            symbol_interner: Lock::new(symbol::Interner::fresh()),
+            span_interner: Lock::new(span_encoding::SpanInterner::default()),
+            hygiene_data: Lock::new(hygiene::HygieneData::new()),
+        }
+    }
+}
+
+scoped_thread_local!(pub static GLOBALS: Globals);
+
 /// Differentiates between real files and common virtual files
 #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
 pub enum FileName {
diff --git a/src/libsyntax_pos/span_encoding.rs b/src/libsyntax_pos/span_encoding.rs
index bf9a832519a..b55fe4bcb26 100644
--- a/src/libsyntax_pos/span_encoding.rs
+++ b/src/libsyntax_pos/span_encoding.rs
@@ -14,11 +14,11 @@
 // The encoding format for inline spans were obtained by optimizing over crates in rustc/libstd.
 // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28
 
+use GLOBALS;
 use {BytePos, SpanData};
 use hygiene::SyntaxContext;
 
 use rustc_data_structures::fx::FxHashMap;
-use std::cell::RefCell;
 use std::hash::{Hash, Hasher};
 
 /// A compressed span.
@@ -133,7 +133,7 @@ fn decode(span: Span) -> SpanData {
 }
 
 #[derive(Default)]
-struct SpanInterner {
+pub struct SpanInterner {
     spans: FxHashMap<SpanData, u32>,
     span_data: Vec<SpanData>,
 }
@@ -156,11 +156,8 @@ impl SpanInterner {
     }
 }
 
-// If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
+// 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 {
-    thread_local!(static INTERNER: RefCell<SpanInterner> = {
-        RefCell::new(SpanInterner::default())
-    });
-    INTERNER.with(|interner| f(&mut *interner.borrow_mut()))
+    GLOBALS.with(|globals| f(&mut *globals.span_interner.lock()))
 }
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index aafdd696b74..e95079f7c88 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -13,9 +13,9 @@
 //! type, and vice versa.
 
 use hygiene::SyntaxContext;
+use GLOBALS;
 
 use serialize::{Decodable, Decoder, Encodable, Encoder};
-use std::cell::RefCell;
 use std::collections::HashMap;
 use std::fmt;
 
@@ -247,7 +247,7 @@ macro_rules! declare_keywords {(
     }
 
     impl Interner {
-        fn fresh() -> Self {
+        pub fn fresh() -> Self {
             Interner::prefill(&[$($string,)*])
         }
     }
@@ -330,12 +330,10 @@ declare_keywords! {
     (60, Union,          "union")
 }
 
-// If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
+// If an interner exists, return it. Otherwise, prepare a fresh one.
+#[inline]
 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
-    thread_local!(static INTERNER: RefCell<Interner> = {
-        RefCell::new(Interner::fresh())
-    });
-    INTERNER.with(|interner| f(&mut *interner.borrow_mut()))
+    GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock()))
 }
 
 /// Represents a string stored in the thread-local interner. Because the
@@ -422,6 +420,7 @@ impl Encodable for InternedString {
 #[cfg(test)]
 mod tests {
     use super::*;
+    use Globals;
 
     #[test]
     fn interner_tests() {
@@ -444,7 +443,9 @@ mod tests {
 
     #[test]
     fn without_first_quote_test() {
-        let i = Ident::from_str("'break");
-        assert_eq!(i.without_first_quote().name, keywords::Break.name());
+        GLOBALS.set(&Globals::new(), || {
+            let i = Ident::from_str("'break");
+            assert_eq!(i.without_first_quote().name, keywords::Break.name());
+        });
     }
 }