diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2015-06-17 00:33:10 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2015-06-19 01:18:43 +0300 |
| commit | d8952e7932823a3f3aa9d4af0ab9fa6f08b18cef (patch) | |
| tree | 756828ce9c1774e4940a2e8f67f2a85c37a5f7a3 | |
| parent | 6061707348ada3245de306c9d38d07250293e58e (diff) | |
| download | rust-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.rs | 1 | ||||
| -rw-r--r-- | src/librustc/middle/ty.rs | 29 |
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 |
