From 66a376ea4f8caf9049c90888c1c1caa9a109b02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 30 Dec 2018 21:19:11 +0100 Subject: [PATCH] Store CtxtInterners for local values in AllArenas --- src/librustc/infer/mod.rs | 13 ++--------- src/librustc/ty/context.rs | 44 ++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index a4a7efdbc9e3e..4414e677fb5b7 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -21,11 +21,10 @@ use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use crate::ty::fold::{TypeFolder, TypeFoldable}; use crate::ty::relate::RelateResult; use crate::ty::subst::{Kind, InternalSubsts, SubstsRef}; -use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners, InferConst}; +use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, InferConst}; use crate::ty::{FloatVid, IntVid, TyVid, ConstVid}; use crate::util::nodemap::FxHashMap; -use arena::SyncDroplessArena; use errors::DiagnosticBuilder; use rustc_data_structures::unify as ut; use std::cell::{Cell, Ref, RefCell, RefMut}; @@ -468,8 +467,6 @@ impl<'tcx> fmt::Display for FixupError<'tcx> { /// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>)`. pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { global_tcx: TyCtxt<'a, 'gcx, 'gcx>, - arena: SyncDroplessArena, - interners: Option>, fresh_tables: Option>>, } @@ -477,8 +474,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> { InferCtxtBuilder { global_tcx: self, - arena: SyncDroplessArena::default(), - interners: None, fresh_tables: None, } } @@ -518,14 +513,10 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { pub fn enter(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R { let InferCtxtBuilder { global_tcx, - ref arena, - ref mut interners, ref fresh_tables, } = *self; let in_progress_tables = fresh_tables.as_ref(); - // Check that we haven't entered before - assert!(interners.is_none()); - global_tcx.enter_local(arena, interners, |tcx| { + global_tcx.enter_local(|tcx| { f(InferCtxt { tcx, in_progress_tables, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index ff218911ffb81..d8f66eb1c8048 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -82,6 +82,7 @@ use crate::hir; pub struct AllArenas<'tcx> { pub global: WorkerLocal>, pub interner: SyncDroplessArena, + pub local_interner: SyncDroplessArena, } impl<'tcx> AllArenas<'tcx> { @@ -89,6 +90,7 @@ impl<'tcx> AllArenas<'tcx> { AllArenas { global: WorkerLocal::new(|_| GlobalArenas::default()), interner: SyncDroplessArena::default(), + local_interner: SyncDroplessArena::default(), } } } @@ -154,7 +156,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { /// Intern a type #[inline(never)] fn intern_ty( - local: &CtxtInterners<'tcx>, + local: &CtxtInterners<'gcx>, global: &CtxtInterners<'gcx>, st: TyKind<'tcx> ) -> Ty<'tcx> { @@ -179,6 +181,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { &ty_struct); } + // This is safe because all the types the ty_struct can point to + // already is in the local arena or the global arena + let ty_struct: TyS<'gcx> = unsafe { + mem::transmute(ty_struct) + }; + Interned(local.arena.alloc(ty_struct)) }).0 } else { @@ -1029,8 +1037,8 @@ pub struct FreeRegionInfo { #[derive(Copy, Clone)] pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> { gcx: &'gcx GlobalCtxt<'gcx>, - interners: &'tcx CtxtInterners<'tcx>, - dummy: PhantomData<&'a ()>, + interners: &'gcx CtxtInterners<'gcx>, + dummy: PhantomData<(&'a (), &'tcx ())>, } impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> { @@ -1045,6 +1053,7 @@ pub struct GlobalCtxt<'tcx> { pub arena: WorkerLocal>, global_arenas: &'tcx WorkerLocal>, global_interners: CtxtInterners<'tcx>, + local_interners: CtxtInterners<'tcx>, cstore: &'tcx CrateStoreDyn, @@ -1262,6 +1271,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { s.fatal(&err); }); let interners = CtxtInterners::new(&arenas.interner); + let local_interners = CtxtInterners::new(&arenas.local_interner); let common = Common { empty_predicates: ty::GenericPredicates { parent: None, @@ -1321,6 +1331,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { arena: WorkerLocal::new(|_| Arena::default()), global_arenas: &arenas.global, global_interners: interners, + local_interners: local_interners, dep_graph, common, types: common_types, @@ -1716,18 +1727,15 @@ impl<'gcx> GlobalCtxt<'gcx> { /// with the same lifetime as `arena`. pub fn enter_local<'tcx, F, R>( &'gcx self, - arena: &'tcx SyncDroplessArena, - interners: &'tcx mut Option>, f: F ) -> R where F: FnOnce(TyCtxt<'tcx, 'gcx, 'tcx>) -> R, 'gcx: 'tcx, { - *interners = Some(CtxtInterners::new(&arena)); let tcx = TyCtxt { gcx: self, - interners: interners.as_ref().unwrap(), + interners: &self.local_interners, dummy: PhantomData, }; ty::tls::with_related_context(tcx.global_tcx(), |icx| { @@ -2333,6 +2341,17 @@ macro_rules! intern_method { pub fn $method(self, v: $alloc) -> &$lt_tcx $ty { let key = ($alloc_to_key)(&v); + let alloc = |v, interners: &'gcx CtxtInterners<'gcx>| { + // This transmutes $alloc<'tcx> to $alloc<'gcx> + let v = unsafe { + mem::transmute(v) + }; + let i: &$lt_tcx $ty = $alloc_method(&interners.arena, v); + // Cast to 'gcx + let i = unsafe { mem::transmute(i) }; + Interned(i) + }; + // HACK(eddyb) Depend on flags being accurate to // determine that all contents are in the global tcx. // See comments on Lift for why we can't use that. @@ -2346,18 +2365,11 @@ macro_rules! intern_method { v); } - Interned($alloc_method(&self.interners.arena, v)) + alloc(v, &self.interners) }).0 } else { self.global_interners.$name.borrow_mut().intern_ref(key, || { - // This transmutes $alloc<'tcx> to $alloc<'gcx> - let v = unsafe { - mem::transmute(v) - }; - let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v); - // Cast to 'gcx - let i = unsafe { mem::transmute(i) }; - Interned(i) + alloc(v, &self.global_interners) }).0 } }