From ec8c2e1ab9bd47c0184a0cbd77f35e9089c9dc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 31 May 2019 10:23:22 +0200 Subject: [PATCH] Use a single CtxtInterners --- src/librustc/ty/context.rs | 164 +++++++------------------------------ 1 file changed, 28 insertions(+), 136 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4710d611d99df..88236a79421f3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - //! Type context book-keeping. use crate::arena::Arena; @@ -67,7 +65,6 @@ use std::ops::{Deref, Bound}; use std::iter; use std::sync::mpsc; use std::sync::Arc; -use std::marker::PhantomData; use rustc_target::spec::abi; use rustc_macros::HashStable; use syntax::ast; @@ -81,14 +78,12 @@ use crate::hir; pub struct AllArenas { pub interner: SyncDroplessArena, - pub local_interner: SyncDroplessArena, } impl AllArenas { pub fn new() -> Self { AllArenas { interner: SyncDroplessArena::default(), - local_interner: SyncDroplessArena::default(), } } } @@ -136,57 +131,21 @@ impl<'tcx> CtxtInterners<'tcx> { /// Intern a type #[inline(never)] - fn intern_ty( - local: &CtxtInterners<'tcx>, - global: &CtxtInterners<'tcx>, - st: TyKind<'tcx>, + fn intern_ty(&self, + st: TyKind<'tcx> ) -> Ty<'tcx> { - let flags = super::flags::FlagComputation::for_sty(&st); - - // 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. - if flags.flags.intersects(ty::TypeFlags::KEEP_IN_LOCAL_TCX) { - local.type_.borrow_mut().intern(st, |st| { - let ty_struct = TyS { - sty: st, - flags: flags.flags, - outer_exclusive_binder: flags.outer_exclusive_binder, - }; + self.type_.borrow_mut().intern(st, |st| { + let flags = super::flags::FlagComputation::for_sty(&st); - // Make sure we don't end up with inference - // types/regions in the global interner - if ptr_eq(local, global) { - bug!("Attempted to intern `{:?}` which contains \ - inference types/regions in the global type context", - &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<'tcx> = unsafe { - mem::transmute(ty_struct) - }; - - Interned(local.arena.alloc(ty_struct)) - }).0 - } else { - global.type_.borrow_mut().intern(st, |st| { - let ty_struct = TyS { - sty: st, - flags: flags.flags, - outer_exclusive_binder: flags.outer_exclusive_binder, - }; + let ty_struct = TyS { + sty: st, + flags: flags.flags, + outer_exclusive_binder: flags.outer_exclusive_binder, + }; - // This is safe because all the types the ty_struct can point to - // already is in the global arena - let ty_struct: TyS<'tcx> = unsafe { - mem::transmute(ty_struct) - }; - Interned(global.arena.alloc(ty_struct)) - }).0 - } + Interned(self.arena.alloc(ty_struct)) + }).0 } } @@ -933,7 +892,7 @@ EnumLiftImpl! { impl<'tcx> CommonTypes<'tcx> { fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> { - let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty); + let mk = |sty| interners.intern_ty(sty); CommonTypes { unit: mk(Tuple(List::empty())), @@ -1015,8 +974,6 @@ pub struct FreeRegionInfo { #[derive(Copy, Clone)] pub struct TyCtxt<'tcx> { gcx: &'tcx GlobalCtxt<'tcx>, - interners: &'tcx CtxtInterners<'tcx>, - dummy: PhantomData<&'tcx ()>, } impl<'tcx> Deref for TyCtxt<'tcx> { @@ -1030,8 +987,7 @@ impl<'tcx> Deref for TyCtxt<'tcx> { pub struct GlobalCtxt<'tcx> { pub arena: WorkerLocal>, - global_interners: CtxtInterners<'tcx>, - local_interners: CtxtInterners<'tcx>, + interners: CtxtInterners<'tcx>, cstore: &'tcx CrateStoreDyn, @@ -1122,8 +1078,6 @@ impl<'tcx> TyCtxt<'tcx> { pub fn global_tcx(self) -> TyCtxt<'tcx> { TyCtxt { gcx: self.gcx, - interners: &self.gcx.global_interners, - dummy: PhantomData, } } @@ -1203,11 +1157,6 @@ impl<'tcx> TyCtxt<'tcx> { value.lift_to_tcx(self.global_tcx()) } - /// Returns `true` if self is the same as self.global_tcx(). - fn is_global(self) -> bool { - ptr_eq(self.interners, &self.global_interners) - } - /// Creates a type context and call the closure with a `TyCtxt` reference /// to the context. The closure enforces that the type context and any interned /// value (types, substs, etc.) can only be used while `ty::tls` has a valid @@ -1229,7 +1178,6 @@ impl<'tcx> TyCtxt<'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, @@ -1287,8 +1235,7 @@ impl<'tcx> TyCtxt<'tcx> { sess: s, cstore, arena: WorkerLocal::new(|_| Arena::default()), - global_interners: interners, - local_interners: local_interners, + interners, dep_graph, common, types: common_types, @@ -1682,8 +1629,6 @@ impl<'tcx> GlobalCtxt<'tcx> { { let tcx = TyCtxt { gcx: self, - interners: &self.local_interners, - dummy: PhantomData, }; ty::tls::with_related_context(tcx.global_tcx(), |icx| { let new_icx = ty::tls::ImplicitCtxt { @@ -1729,11 +1674,7 @@ macro_rules! nop_lift { type Lifted = $lifted; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { if tcx.interners.arena.in_arena(*self as *const _) { - return Some(unsafe { mem::transmute(*self) }); - } - // Also try in the global tcx if we're not that. - if !tcx.is_global() { - self.lift_to_tcx(tcx.global_tcx()) + Some(unsafe { mem::transmute(*self) }) } else { None } @@ -1751,11 +1692,7 @@ macro_rules! nop_list_lift { return Some(List::empty()); } if tcx.interners.arena.in_arena(*self as *const _) { - return Some(unsafe { mem::transmute(*self) }); - } - // Also try in the global tcx if we're not that. - if !tcx.is_global() { - self.lift_to_tcx(tcx.global_tcx()) + Some(unsafe { mem::transmute(*self) }) } else { None } @@ -1785,7 +1722,6 @@ pub mod tls { use std::fmt; use std::mem; - use std::marker::PhantomData; use syntax_pos; use crate::ty::query; use errors::{Diagnostic, TRACK_DIAGNOSTICS}; @@ -1949,8 +1885,6 @@ pub mod tls { let tcx = TyCtxt { gcx, - interners: &gcx.global_interners, - dummy: PhantomData, }; let icx = ImplicitCtxt { tcx, @@ -1981,8 +1915,6 @@ pub mod tls { let gcx = &*(gcx as *const GlobalCtxt<'_>); let tcx = TyCtxt { gcx, - interners: &gcx.global_interners, - dummy: PhantomData, }; let icx = ImplicitCtxt { query: None, @@ -2041,26 +1973,6 @@ pub mod tls { }) } - /// Allows access to the current ImplicitCtxt whose tcx field has the same global - /// interner and local interner as the tcx argument passed in. This means the closure - /// is given an ImplicitCtxt with the same 'tcx and 'tcx lifetimes as the TyCtxt passed in. - /// This will panic if you pass it a TyCtxt which has a different global interner or - /// a different local interner from the current ImplicitCtxt's tcx field. - #[inline] - pub fn with_fully_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R - where - F: for<'b> FnOnce(&ImplicitCtxt<'b, 'tcx>) -> R, - { - with_context(|context| { - unsafe { - assert!(ptr_eq(context.tcx.gcx, tcx.gcx)); - assert!(ptr_eq(context.tcx.interners, tcx.interners)); - let context: &ImplicitCtxt<'_, '_> = mem::transmute(context); - f(context) - } - }) - } - /// Allows access to the TyCtxt in the current ImplicitCtxt. /// Panics if there is no ImplicitCtxt available #[inline] @@ -2288,39 +2200,22 @@ impl<'tcx> Borrow<[Goal<'tcx>]> for Interned<'tcx, List>> { macro_rules! intern_method { ($lt_tcx:tt, $name:ident: $method:ident($alloc:ty, $alloc_method:expr, - $alloc_to_key:expr, - $keep_in_local_tcx:expr) -> $ty:ty) => { + $alloc_to_key:expr) -> $ty:ty) => { impl<$lt_tcx> TyCtxt<$lt_tcx> { pub fn $method(self, v: $alloc) -> &$lt_tcx $ty { let key = ($alloc_to_key)(&v); - // 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. - if ($keep_in_local_tcx)(&v) { - self.interners.$name.borrow_mut().intern_ref(key, || { - // Make sure we don't end up with inference - // types/regions in the global tcx. - if self.is_global() { - bug!("Attempted to intern `{:?}` which contains \ - inference types/regions in the global type context", - v); - } + self.interners.$name.borrow_mut().intern_ref(key, || { + Interned($alloc_method(&self.interners.arena, v)) - Interned($alloc_method(&self.interners.arena, v)) - }).0 - } else { - self.global_interners.$name.borrow_mut().intern_ref(key, || { - Interned($alloc_method(&self.global_interners.arena, v)) - }).0 - } + }).0 } } } } macro_rules! direct_interners { - ($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => { + ($lt_tcx:tt, $($name:ident: $method:ident($ty:ty)),+) => { $(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> { fn eq(&self, other: &Self) -> bool { self.0 == other.0 @@ -2339,8 +2234,7 @@ macro_rules! direct_interners { $lt_tcx, $name: $method($ty, |a: &$lt_tcx SyncDroplessArena, v| -> &$lt_tcx $ty { a.alloc(v) }, - |x| x, - $keep_in_local_tcx) -> $ty);)+ + |x| x) -> $ty);)+ } } @@ -2349,9 +2243,9 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool { } direct_interners!('tcx, - region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind, - goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>, - const_: mk_const(|c: &Const<'_>| keep_local(&c)) -> Const<'tcx> + region: mk_region(RegionKind), + goal: mk_goal(GoalKind<'tcx>), + const_: mk_const(Const<'tcx>) ); macro_rules! slice_interners { @@ -2359,8 +2253,7 @@ macro_rules! slice_interners { $(intern_method!( 'tcx, $field: $method( &[$ty], |a, v| List::from_arena(a, v), - Deref::deref, - |xs: &[$ty]| xs.iter().any(keep_local)) -> List<$ty>);)+ + Deref::deref) -> List<$ty>);)+ ); } @@ -2384,8 +2277,7 @@ intern_method! { canonical_var_infos: _intern_canonical_var_infos( &[CanonicalVarInfo], |a, v| List::from_arena(a, v), - Deref::deref, - |_xs: &[CanonicalVarInfo]| -> bool { false } + Deref::deref ) -> List } @@ -2431,7 +2323,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> { - CtxtInterners::intern_ty(&self.interners, &self.global_interners, st) + self.interners.intern_ty(st) } pub fn mk_mach_int(self, tm: ast::IntTy) -> Ty<'tcx> {