Store CtxtInterners for local values in AllArenas
This commit is contained in:
parent
3ade426ede
commit
66a376ea4f
2 changed files with 30 additions and 27 deletions
|
@ -21,11 +21,10 @@ use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||||
use crate::ty::fold::{TypeFolder, TypeFoldable};
|
use crate::ty::fold::{TypeFolder, TypeFoldable};
|
||||||
use crate::ty::relate::RelateResult;
|
use crate::ty::relate::RelateResult;
|
||||||
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
|
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::ty::{FloatVid, IntVid, TyVid, ConstVid};
|
||||||
use crate::util::nodemap::FxHashMap;
|
use crate::util::nodemap::FxHashMap;
|
||||||
|
|
||||||
use arena::SyncDroplessArena;
|
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
use rustc_data_structures::unify as ut;
|
use rustc_data_structures::unify as ut;
|
||||||
use std::cell::{Cell, Ref, RefCell, RefMut};
|
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>)`.
|
/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>)`.
|
||||||
pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||||
global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||||
arena: SyncDroplessArena,
|
|
||||||
interners: Option<CtxtInterners<'tcx>>,
|
|
||||||
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
|
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,8 +474,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
|
||||||
pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
||||||
InferCtxtBuilder {
|
InferCtxtBuilder {
|
||||||
global_tcx: self,
|
global_tcx: self,
|
||||||
arena: SyncDroplessArena::default(),
|
|
||||||
interners: None,
|
|
||||||
fresh_tables: None,
|
fresh_tables: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,14 +513,10 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
||||||
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
|
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
|
||||||
let InferCtxtBuilder {
|
let InferCtxtBuilder {
|
||||||
global_tcx,
|
global_tcx,
|
||||||
ref arena,
|
|
||||||
ref mut interners,
|
|
||||||
ref fresh_tables,
|
ref fresh_tables,
|
||||||
} = *self;
|
} = *self;
|
||||||
let in_progress_tables = fresh_tables.as_ref();
|
let in_progress_tables = fresh_tables.as_ref();
|
||||||
// Check that we haven't entered before
|
global_tcx.enter_local(|tcx| {
|
||||||
assert!(interners.is_none());
|
|
||||||
global_tcx.enter_local(arena, interners, |tcx| {
|
|
||||||
f(InferCtxt {
|
f(InferCtxt {
|
||||||
tcx,
|
tcx,
|
||||||
in_progress_tables,
|
in_progress_tables,
|
||||||
|
|
|
@ -82,6 +82,7 @@ use crate::hir;
|
||||||
pub struct AllArenas<'tcx> {
|
pub struct AllArenas<'tcx> {
|
||||||
pub global: WorkerLocal<GlobalArenas<'tcx>>,
|
pub global: WorkerLocal<GlobalArenas<'tcx>>,
|
||||||
pub interner: SyncDroplessArena,
|
pub interner: SyncDroplessArena,
|
||||||
|
pub local_interner: SyncDroplessArena,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> AllArenas<'tcx> {
|
impl<'tcx> AllArenas<'tcx> {
|
||||||
|
@ -89,6 +90,7 @@ impl<'tcx> AllArenas<'tcx> {
|
||||||
AllArenas {
|
AllArenas {
|
||||||
global: WorkerLocal::new(|_| GlobalArenas::default()),
|
global: WorkerLocal::new(|_| GlobalArenas::default()),
|
||||||
interner: SyncDroplessArena::default(),
|
interner: SyncDroplessArena::default(),
|
||||||
|
local_interner: SyncDroplessArena::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +156,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
|
||||||
/// Intern a type
|
/// Intern a type
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn intern_ty(
|
fn intern_ty(
|
||||||
local: &CtxtInterners<'tcx>,
|
local: &CtxtInterners<'gcx>,
|
||||||
global: &CtxtInterners<'gcx>,
|
global: &CtxtInterners<'gcx>,
|
||||||
st: TyKind<'tcx>
|
st: TyKind<'tcx>
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
|
@ -179,6 +181,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
|
||||||
&ty_struct);
|
&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))
|
Interned(local.arena.alloc(ty_struct))
|
||||||
}).0
|
}).0
|
||||||
} else {
|
} else {
|
||||||
|
@ -1029,8 +1037,8 @@ pub struct FreeRegionInfo {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||||
gcx: &'gcx GlobalCtxt<'gcx>,
|
gcx: &'gcx GlobalCtxt<'gcx>,
|
||||||
interners: &'tcx CtxtInterners<'tcx>,
|
interners: &'gcx CtxtInterners<'gcx>,
|
||||||
dummy: PhantomData<&'a ()>,
|
dummy: PhantomData<(&'a (), &'tcx ())>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
|
impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
|
||||||
|
@ -1045,6 +1053,7 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
pub arena: WorkerLocal<Arena<'tcx>>,
|
pub arena: WorkerLocal<Arena<'tcx>>,
|
||||||
global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
|
global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
|
||||||
global_interners: CtxtInterners<'tcx>,
|
global_interners: CtxtInterners<'tcx>,
|
||||||
|
local_interners: CtxtInterners<'tcx>,
|
||||||
|
|
||||||
cstore: &'tcx CrateStoreDyn,
|
cstore: &'tcx CrateStoreDyn,
|
||||||
|
|
||||||
|
@ -1262,6 +1271,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
s.fatal(&err);
|
s.fatal(&err);
|
||||||
});
|
});
|
||||||
let interners = CtxtInterners::new(&arenas.interner);
|
let interners = CtxtInterners::new(&arenas.interner);
|
||||||
|
let local_interners = CtxtInterners::new(&arenas.local_interner);
|
||||||
let common = Common {
|
let common = Common {
|
||||||
empty_predicates: ty::GenericPredicates {
|
empty_predicates: ty::GenericPredicates {
|
||||||
parent: None,
|
parent: None,
|
||||||
|
@ -1321,6 +1331,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
arena: WorkerLocal::new(|_| Arena::default()),
|
arena: WorkerLocal::new(|_| Arena::default()),
|
||||||
global_arenas: &arenas.global,
|
global_arenas: &arenas.global,
|
||||||
global_interners: interners,
|
global_interners: interners,
|
||||||
|
local_interners: local_interners,
|
||||||
dep_graph,
|
dep_graph,
|
||||||
common,
|
common,
|
||||||
types: common_types,
|
types: common_types,
|
||||||
|
@ -1716,18 +1727,15 @@ impl<'gcx> GlobalCtxt<'gcx> {
|
||||||
/// with the same lifetime as `arena`.
|
/// with the same lifetime as `arena`.
|
||||||
pub fn enter_local<'tcx, F, R>(
|
pub fn enter_local<'tcx, F, R>(
|
||||||
&'gcx self,
|
&'gcx self,
|
||||||
arena: &'tcx SyncDroplessArena,
|
|
||||||
interners: &'tcx mut Option<CtxtInterners<'tcx>>,
|
|
||||||
f: F
|
f: F
|
||||||
) -> R
|
) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(TyCtxt<'tcx, 'gcx, 'tcx>) -> R,
|
F: FnOnce(TyCtxt<'tcx, 'gcx, 'tcx>) -> R,
|
||||||
'gcx: 'tcx,
|
'gcx: 'tcx,
|
||||||
{
|
{
|
||||||
*interners = Some(CtxtInterners::new(&arena));
|
|
||||||
let tcx = TyCtxt {
|
let tcx = TyCtxt {
|
||||||
gcx: self,
|
gcx: self,
|
||||||
interners: interners.as_ref().unwrap(),
|
interners: &self.local_interners,
|
||||||
dummy: PhantomData,
|
dummy: PhantomData,
|
||||||
};
|
};
|
||||||
ty::tls::with_related_context(tcx.global_tcx(), |icx| {
|
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 {
|
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
|
||||||
let key = ($alloc_to_key)(&v);
|
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
|
// HACK(eddyb) Depend on flags being accurate to
|
||||||
// determine that all contents are in the global tcx.
|
// determine that all contents are in the global tcx.
|
||||||
// See comments on Lift for why we can't use that.
|
// See comments on Lift for why we can't use that.
|
||||||
|
@ -2346,18 +2365,11 @@ macro_rules! intern_method {
|
||||||
v);
|
v);
|
||||||
}
|
}
|
||||||
|
|
||||||
Interned($alloc_method(&self.interners.arena, v))
|
alloc(v, &self.interners)
|
||||||
}).0
|
}).0
|
||||||
} else {
|
} else {
|
||||||
self.global_interners.$name.borrow_mut().intern_ref(key, || {
|
self.global_interners.$name.borrow_mut().intern_ref(key, || {
|
||||||
// This transmutes $alloc<'tcx> to $alloc<'gcx>
|
alloc(v, &self.global_interners)
|
||||||
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)
|
|
||||||
}).0
|
}).0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue