about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-06-17 00:33:10 +0300
committerEduard Burtescu <edy.burt@gmail.com>2015-06-19 01:18:43 +0300
commitd8952e7932823a3f3aa9d4af0ab9fa6f08b18cef (patch)
tree756828ce9c1774e4940a2e8f67f2a85c37a5f7a3
parent6061707348ada3245de306c9d38d07250293e58e (diff)
downloadrust-d8952e7932823a3f3aa9d4af0ab9fa6f08b18cef.tar.gz
rust-d8952e7932823a3f3aa9d4af0ab9fa6f08b18cef.zip
rustc: store the type context in TLS and allow safe access to it.
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/ty.rs29
2 files changed, 26 insertions, 4 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 240aaae0e55..c19ba19f5b7 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -51,6 +51,7 @@
 #![feature(ref_slice)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
+#![feature(scoped_tls)]
 #![feature(slice_bytes)]
 #![feature(slice_extras)]
 #![feature(slice_patterns)]
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 474865305a0..84d874909aa 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -804,6 +804,29 @@ impl<'tcx> ctxt<'tcx> {
     }
 }
 
+pub mod tls {
+    use middle::ty;
+    use session::Session;
+
+    /// Marker type used for the scoped TLS slot.
+    /// The type context cannot be used directly because the scoped TLS
+    /// in libstd doesn't allow types generic over lifetimes.
+    struct ThreadLocalTyCx;
+
+    scoped_thread_local!(static TLS_TCX: ThreadLocalTyCx);
+
+    pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F)
+                                                           -> (Session, R) {
+        let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
+        let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
+        (tcx.sess, result)
+    }
+
+    pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
+        TLS_TCX.with(|tcx| f(unsafe { &*(tcx as *const _ as *const ty::ctxt) }))
+    }
+}
+
 // Flags that we track on types. These flags are propagated upwards
 // through the type during type construction, so that we can quickly
 // check whether the type has various kinds of types in it without
@@ -2824,7 +2847,7 @@ pub fn with_ctxt<'tcx, F, R>(s: Session,
     let mut interner = FnvHashMap();
     let common_types = CommonTypes::new(&arenas.type_, &mut interner);
 
-    let tcx = ctxt {
+    tls::enter(ctxt {
         arenas: arenas,
         interner: RefCell::new(interner),
         substs_interner: RefCell::new(FnvHashMap()),
@@ -2886,9 +2909,7 @@ pub fn with_ctxt<'tcx, F, R>(s: Session,
         const_qualif_map: RefCell::new(NodeMap()),
         custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
         cast_kinds: RefCell::new(NodeMap()),
-   };
-   let result = f(&tcx);
-   (tcx.sess, result)
+   }, f)
 }
 
 // Type constructors