Skip to content

Commit d8952e7

Browse files
committed
rustc: store the type context in TLS and allow safe access to it.
1 parent 6061707 commit d8952e7

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#![feature(ref_slice)]
5252
#![feature(rustc_diagnostic_macros)]
5353
#![feature(rustc_private)]
54+
#![feature(scoped_tls)]
5455
#![feature(slice_bytes)]
5556
#![feature(slice_extras)]
5657
#![feature(slice_patterns)]

src/librustc/middle/ty.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,29 @@ impl<'tcx> ctxt<'tcx> {
804804
}
805805
}
806806

807+
pub mod tls {
808+
use middle::ty;
809+
use session::Session;
810+
811+
/// Marker type used for the scoped TLS slot.
812+
/// The type context cannot be used directly because the scoped TLS
813+
/// in libstd doesn't allow types generic over lifetimes.
814+
struct ThreadLocalTyCx;
815+
816+
scoped_thread_local!(static TLS_TCX: ThreadLocalTyCx);
817+
818+
pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F)
819+
-> (Session, R) {
820+
let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
821+
let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
822+
(tcx.sess, result)
823+
}
824+
825+
pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
826+
TLS_TCX.with(|tcx| f(unsafe { &*(tcx as *const _ as *const ty::ctxt) }))
827+
}
828+
}
829+
807830
// Flags that we track on types. These flags are propagated upwards
808831
// through the type during type construction, so that we can quickly
809832
// 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,
28242847
let mut interner = FnvHashMap();
28252848
let common_types = CommonTypes::new(&arenas.type_, &mut interner);
28262849

2827-
let tcx = ctxt {
2850+
tls::enter(ctxt {
28282851
arenas: arenas,
28292852
interner: RefCell::new(interner),
28302853
substs_interner: RefCell::new(FnvHashMap()),
@@ -2886,9 +2909,7 @@ pub fn with_ctxt<'tcx, F, R>(s: Session,
28862909
const_qualif_map: RefCell::new(NodeMap()),
28872910
custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
28882911
cast_kinds: RefCell::new(NodeMap()),
2889-
};
2890-
let result = f(&tcx);
2891-
(tcx.sess, result)
2912+
}, f)
28922913
}
28932914

28942915
// Type constructors

0 commit comments

Comments
 (0)