Skip to content

Commit fe63e47

Browse files
committed
Auto merge of #50332 - Zoxc:interner-split, r=michaelwoerister
Only lookup types in one interner
2 parents 41707d8 + e245d69 commit fe63e47

File tree

1 file changed

+68
-77
lines changed

1 file changed

+68
-77
lines changed

src/librustc/ty/context.rs

+68-77
Original file line numberDiff line numberDiff line change
@@ -162,66 +162,65 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
162162
}
163163
}
164164

165-
/// Intern a type. global_interners is Some only if this is
166-
/// a local interner and global_interners is its counterpart.
167-
fn intern_ty(&self, st: TypeVariants<'tcx>,
168-
global_interners: Option<&CtxtInterners<'gcx>>)
169-
-> Ty<'tcx> {
170-
let ty = {
171-
let mut interner = self.type_.borrow_mut();
165+
/// Intern a type
166+
fn intern_ty(
167+
local: &CtxtInterners<'tcx>,
168+
global: &CtxtInterners<'gcx>,
169+
st: TypeVariants<'tcx>
170+
) -> Ty<'tcx> {
171+
let flags = super::flags::FlagComputation::for_sty(&st);
172+
173+
// HACK(eddyb) Depend on flags being accurate to
174+
// determine that all contents are in the global tcx.
175+
// See comments on Lift for why we can't use that.
176+
if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
177+
let mut interner = local.type_.borrow_mut();
172178
if let Some(&Interned(ty)) = interner.get(&st) {
173179
return ty;
174180
}
175-
let global_interner = global_interners.map(|interners| {
176-
(interners.type_.borrow_mut(), &interners.arena)
177-
});
178-
if let Some((ref type_, _)) = global_interner {
179-
if let Some(&Interned(ty)) = type_.get(&st) {
180-
return ty;
181-
}
182-
}
183181

184-
let flags = super::flags::FlagComputation::for_sty(&st);
185182
let ty_struct = TyS {
186183
sty: st,
187184
flags: flags.flags,
188185
region_depth: flags.depth,
189186
};
190187

191-
// HACK(eddyb) Depend on flags being accurate to
192-
// determine that all contents are in the global tcx.
193-
// See comments on Lift for why we can't use that.
194-
if !flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
195-
if let Some((mut type_, arena)) = global_interner {
196-
let ty_struct: TyS<'gcx> = unsafe {
197-
mem::transmute(ty_struct)
198-
};
199-
let ty: Ty<'gcx> = arena.alloc(ty_struct);
200-
type_.insert(Interned(ty));
201-
return ty;
202-
}
203-
} else {
204-
// Make sure we don't end up with inference
205-
// types/regions in the global tcx.
206-
if global_interner.is_none() {
207-
drop(interner);
208-
bug!("Attempted to intern `{:?}` which contains \
209-
inference types/regions in the global type context",
210-
&ty_struct);
211-
}
188+
// Make sure we don't end up with inference
189+
// types/regions in the global interner
190+
if local as *const _ as usize == global as *const _ as usize {
191+
bug!("Attempted to intern `{:?}` which contains \
192+
inference types/regions in the global type context",
193+
&ty_struct);
212194
}
213195

214196
// Don't be &mut TyS.
215-
let ty: Ty<'tcx> = self.arena.alloc(ty_struct);
197+
let ty: Ty<'tcx> = local.arena.alloc(ty_struct);
216198
interner.insert(Interned(ty));
217199
ty
218-
};
200+
} else {
201+
let mut interner = global.type_.borrow_mut();
202+
if let Some(&Interned(ty)) = interner.get(&st) {
203+
return ty;
204+
}
219205

220-
debug!("Interned type: {:?} Pointer: {:?}",
221-
ty, ty as *const TyS);
222-
ty
223-
}
206+
let ty_struct = TyS {
207+
sty: st,
208+
flags: flags.flags,
209+
region_depth: flags.depth,
210+
};
211+
212+
// This is safe because all the types the ty_struct can point to
213+
// already is in the global arena
214+
let ty_struct: TyS<'gcx> = unsafe {
215+
mem::transmute(ty_struct)
216+
};
224217

218+
// Don't be &mut TyS.
219+
let ty: Ty<'gcx> = global.arena.alloc(ty_struct);
220+
interner.insert(Interned(ty));
221+
ty
222+
}
223+
}
225224
}
226225

227226
pub struct CommonTypes<'tcx> {
@@ -796,7 +795,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
796795

797796
impl<'tcx> CommonTypes<'tcx> {
798797
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
799-
let mk = |sty| interners.intern_ty(sty, None);
798+
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
800799
let mk_region = |r| {
801800
if let Some(r) = interners.region.borrow().get(&r) {
802801
return r.0;
@@ -2130,43 +2129,42 @@ macro_rules! intern_method {
21302129
$keep_in_local_tcx:expr) -> $ty:ty) => {
21312130
impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
21322131
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
2133-
{
2134-
let key = ($alloc_to_key)(&v);
2135-
if let Some(i) = self.interners.$name.borrow().get(key) {
2136-
return i.0;
2137-
}
2138-
if !self.is_global() {
2139-
if let Some(i) = self.global_interners.$name.borrow().get(key) {
2140-
return i.0;
2141-
}
2142-
}
2143-
}
2132+
let key = ($alloc_to_key)(&v);
21442133

21452134
// HACK(eddyb) Depend on flags being accurate to
21462135
// determine that all contents are in the global tcx.
21472136
// See comments on Lift for why we can't use that.
2148-
if !($keep_in_local_tcx)(&v) {
2149-
if !self.is_global() {
2150-
let v = unsafe {
2151-
mem::transmute(v)
2152-
};
2153-
let i = ($alloc_to_ret)(self.global_interners.arena.$alloc_method(v));
2154-
self.global_interners.$name.borrow_mut().insert(Interned(i));
2155-
return i;
2137+
if ($keep_in_local_tcx)(&v) {
2138+
let mut interner = self.interners.$name.borrow_mut();
2139+
if let Some(&Interned(v)) = interner.get(key) {
2140+
return v;
21562141
}
2157-
} else {
2142+
21582143
// Make sure we don't end up with inference
21592144
// types/regions in the global tcx.
21602145
if self.is_global() {
21612146
bug!("Attempted to intern `{:?}` which contains \
21622147
inference types/regions in the global type context",
21632148
v);
21642149
}
2165-
}
21662150

2167-
let i = ($alloc_to_ret)(self.interners.arena.$alloc_method(v));
2168-
self.interners.$name.borrow_mut().insert(Interned(i));
2169-
i
2151+
let i = ($alloc_to_ret)(self.interners.arena.$alloc_method(v));
2152+
interner.insert(Interned(i));
2153+
i
2154+
} else {
2155+
let mut interner = self.global_interners.$name.borrow_mut();
2156+
if let Some(&Interned(v)) = interner.get(key) {
2157+
return v;
2158+
}
2159+
2160+
// This transmutes $alloc<'tcx> to $alloc<'gcx>
2161+
let v = unsafe {
2162+
mem::transmute(v)
2163+
};
2164+
let i = ($alloc_to_ret)(self.global_interners.arena.$alloc_method(v));
2165+
interner.insert(Interned(i));
2166+
i
2167+
}
21702168
}
21712169
}
21722170
}
@@ -2274,15 +2272,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
22742272
self.mk_fn_ptr(converted_sig)
22752273
}
22762274

2277-
// Interns a type/name combination, stores the resulting box in cx.interners,
2278-
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
2279-
pub fn mk_ty(self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
2280-
let global_interners = if !self.is_global() {
2281-
Some(&self.global_interners)
2282-
} else {
2283-
None
2284-
};
2285-
self.interners.intern_ty(st, global_interners)
2275+
pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
2276+
CtxtInterners::intern_ty(&self.interners, &self.global_interners, st)
22862277
}
22872278

22882279
pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {

0 commit comments

Comments
 (0)