Skip to content

Commit 3d038cc

Browse files
committed
Only lookup types in one interner
1 parent ede7f94 commit 3d038cc

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

src/librustc/ty/context.rs

+52-8
Original file line numberDiff line numberDiff line change
@@ -2268,15 +2268,59 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
22682268
self.mk_fn_ptr(converted_sig)
22692269
}
22702270

2271-
// Interns a type/name combination, stores the resulting box in cx.interners,
2272-
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
2273-
pub fn mk_ty(self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
2274-
let global_interners = if !self.is_global() {
2275-
Some(&self.global_interners)
2271+
pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
2272+
let flags = super::flags::FlagComputation::for_sty(&st);
2273+
2274+
// HACK(eddyb) Depend on flags being accurate to
2275+
// determine that all contents are in the global tcx.
2276+
// See comments on Lift for why we can't use that.
2277+
if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) {
2278+
let mut interner = self.interners.type_.borrow_mut();
2279+
if let Some(&Interned(ty)) = interner.get(&st) {
2280+
return ty;
2281+
}
2282+
2283+
let ty_struct = TyS {
2284+
sty: st,
2285+
flags: flags.flags,
2286+
region_depth: flags.depth,
2287+
};
2288+
2289+
// Make sure we don't end up with inference
2290+
// types/regions in the global tcx.
2291+
if self.is_global() {
2292+
bug!("Attempted to intern `{:?}` which contains \
2293+
inference types/regions in the global type context",
2294+
&ty_struct);
2295+
}
2296+
2297+
// Don't be &mut TyS.
2298+
let ty: Ty<'tcx> = self.interners.arena.alloc(ty_struct);
2299+
interner.insert(Interned(ty));
2300+
ty
22762301
} else {
2277-
None
2278-
};
2279-
self.interners.intern_ty(st, global_interners)
2302+
let mut interner = self.global_interners.type_.borrow_mut();
2303+
if let Some(&Interned(ty)) = interner.get(&st) {
2304+
return ty;
2305+
}
2306+
2307+
let ty_struct = TyS {
2308+
sty: st,
2309+
flags: flags.flags,
2310+
region_depth: flags.depth,
2311+
};
2312+
2313+
// This is safe because all the types the ty_struct can point to
2314+
// already is in the global arena
2315+
let ty_struct: TyS<'gcx> = unsafe {
2316+
mem::transmute(ty_struct)
2317+
};
2318+
2319+
// Don't be &mut TyS.
2320+
let ty: Ty<'gcx> = self.global_interners.arena.alloc(ty_struct);
2321+
interner.insert(Interned(ty));
2322+
ty
2323+
}
22802324
}
22812325

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

0 commit comments

Comments
 (0)