Auto merge of #50197 - nikomatsakis:skolemize-out-of-tcx, r=eddyb

move skolemized regions into global tcx

Experimental branch to move skolemized regions into global tcx. This is probably not what we want long term but may be convenient to unblock @sgrif in the short term.

I'd like to do a perf run, though the main concern I guess would be memory usage.

r? @eddyb
This commit is contained in:
bors 2018-05-01 00:16:16 +00:00
commit 2a8ad90930
8 changed files with 36 additions and 35 deletions

View File

@ -409,7 +409,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
let tcx = self.selcx.tcx().global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() {
if substs.needs_infer() || substs.has_skol() {
let identity_substs = Substs::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {

View File

@ -196,7 +196,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
let tcx = self.infcx.tcx.global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() {
if substs.needs_infer() || substs.has_skol() {
let identity_substs = Substs::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {

View File

@ -2119,7 +2119,7 @@ macro_rules! intern_method {
$alloc_method:ident,
$alloc_to_key:expr,
$alloc_to_ret:expr,
$needs_infer:expr) -> $ty:ty) => {
$keep_in_local_tcx:expr) -> $ty:ty) => {
impl<'a, 'gcx, $lt_tcx> TyCtxt<'a, 'gcx, $lt_tcx> {
pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
{
@ -2137,7 +2137,7 @@ macro_rules! intern_method {
// 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 !($needs_infer)(&v) {
if !($keep_in_local_tcx)(&v) {
if !self.is_global() {
let v = unsafe {
mem::transmute(v)
@ -2165,7 +2165,7 @@ macro_rules! intern_method {
}
macro_rules! direct_interners {
($lt_tcx:tt, $($name:ident: $method:ident($needs_infer:expr) -> $ty:ty),+) => {
($lt_tcx:tt, $($name:ident: $method:ident($keep_in_local_tcx:expr) -> $ty:ty),+) => {
$(impl<$lt_tcx> PartialEq for Interned<$lt_tcx, $ty> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
@ -2180,7 +2180,10 @@ macro_rules! direct_interners {
}
}
intern_method!($lt_tcx, $name: $method($ty, alloc, |x| x, |x| x, $needs_infer) -> $ty);)+
intern_method!(
$lt_tcx,
$name: $method($ty, alloc, |x| x, |x| x, $keep_in_local_tcx) -> $ty
);)+
}
}
@ -2189,12 +2192,7 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
}
direct_interners!('tcx,
region: mk_region(|r| {
match r {
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
_ => false
}
}) -> RegionKind,
region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
const_: mk_const(|c: &Const| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>
);

View File

@ -91,6 +91,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn needs_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
}
fn has_skol(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_SKOL)
}
fn needs_subst(&self) -> bool {
self.has_type_flags(TypeFlags::NEEDS_SUBST)
}
@ -111,15 +114,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}
fn is_normalized_for_trans(&self) -> bool {
!self.has_type_flags(TypeFlags::HAS_RE_INFER |
TypeFlags::HAS_FREE_REGIONS |
TypeFlags::HAS_TY_INFER |
TypeFlags::HAS_PARAMS |
TypeFlags::HAS_NORMALIZABLE_PROJECTION |
TypeFlags::HAS_TY_ERR |
TypeFlags::HAS_SELF)
}
/// Indicates whether this value references only 'global'
/// types/lifetimes that are the same regardless of what fn we are
/// in. This is used for caching. Errs on the side of returning

View File

@ -1476,7 +1476,11 @@ impl<'tcx> ParamEnv<'tcx> {
}
Reveal::All => {
if value.needs_infer() || value.has_param_types() || value.has_self_ty() {
if value.has_skol()
|| value.needs_infer()
|| value.has_param_types()
|| value.has_self_ty()
{
ParamEnvAnd {
param_env: self,
value,

View File

@ -1171,13 +1171,6 @@ impl RegionKind {
}
}
pub fn needs_infer(&self) -> bool {
match *self {
ty::ReVar(..) | ty::ReSkolemized(..) => true,
_ => false
}
}
pub fn escapes_depth(&self, depth: u32) -> bool {
match *self {
ty::ReLateBound(debruijn, _) => debruijn.depth > depth,
@ -1195,20 +1188,29 @@ impl RegionKind {
}
}
pub fn keep_in_local_tcx(&self) -> bool {
if let ty::ReVar(..) = self {
true
} else {
false
}
}
pub fn type_flags(&self) -> TypeFlags {
let mut flags = TypeFlags::empty();
if self.keep_in_local_tcx() {
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
}
match *self {
ty::ReVar(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_RE_INFER;
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
}
ty::ReSkolemized(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_RE_INFER;
flags = flags | TypeFlags::HAS_RE_SKOL;
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
}
ty::ReLateBound(..) => { }
ty::ReEarlyBound(..) => {

View File

@ -1485,7 +1485,10 @@ impl<'tcx> Candidate<'tcx> {
// inference variables or other artifacts. This
// means they are safe to put into the
// `WhereClausePick`.
assert!(!trait_ref.skip_binder().substs.needs_infer());
assert!(
!trait_ref.skip_binder().substs.needs_infer()
&& !trait_ref.skip_binder().substs.has_skol()
);
WhereClausePick(trait_ref.clone())
}

View File

@ -107,7 +107,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
assert!(!ty.needs_infer());
assert!(!ty.needs_infer() && !ty.has_skol());
self.tables.node_types_mut().insert(hir_id, ty);
}
@ -431,7 +431,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) {
let substs = self.resolve(&substs, &span);
debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs);
assert!(!substs.needs_infer());
assert!(!substs.needs_infer() && !substs.has_skol());
self.tables.node_substs_mut().insert(hir_id, substs);
}
}