1
Fork 0

Add const type flags

Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
This commit is contained in:
varkor 2019-02-20 01:15:21 +00:00
parent 29c272d4ed
commit cbf5d22bcd
2 changed files with 34 additions and 17 deletions

View file

@ -1,5 +1,6 @@
use crate::ty::subst::SubstsRef;
use crate::ty::{self, Ty, TypeFlags, TypeFoldable};
use crate::ty::subst::{SubstsRef, UnpackedKind};
use crate::ty::{self, Ty, TypeFlags, TypeFoldable, InferConst};
use crate::mir::interpret::ConstValue;
#[derive(Debug)]
pub struct FlagComputation {
@ -232,6 +233,21 @@ impl FlagComputation {
}
}
fn add_const(&mut self, c: &ty::LazyConst<'_>) {
match c {
ty::LazyConst::Unevaluated(_, substs) => self.add_substs(substs),
// Only done to add the binder for the type. The type flags are
// included in `Const::type_flags`.
ty::LazyConst::Evaluated(ty::Const { ty, val }) => {
self.add_ty(ty);
if let ConstValue::Infer(InferConst::Canonical(debruijn, _)) = val {
self.add_binder(*debruijn)
}
}
}
self.add_flags(c.type_flags());
}
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
self.add_substs(projection.substs);
self.add_ty(projection.ty);
@ -242,12 +258,12 @@ impl FlagComputation {
}
fn add_substs(&mut self, substs: SubstsRef<'_>) {
for ty in substs.types() {
self.add_ty(ty);
}
for r in substs.regions() {
self.add_region(r);
for kind in substs {
match kind.unpack() {
UnpackedKind::Type(ty) => self.add_ty(ty),
UnpackedKind::Lifetime(lt) => self.add_region(lt),
UnpackedKind::Const(ct) => self.add_const(ct),
}
}
}
}

View file

@ -91,7 +91,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
fn needs_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
self.has_type_flags(
TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER
)
}
fn has_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER | TypeFlags::HAS_TY_PLACEHOLDER)
@ -117,7 +119,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
}
/// Indicates whether this value references only 'global'
/// types/lifetimes that are the same regardless of what fn we are
/// generic parameters that are the same regardless of what fn we are
/// in. This is used for caching.
fn is_global(&self) -> bool {
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
@ -841,14 +843,13 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}
fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
if let ty::LazyConst::Unevaluated(..) = c {
let projection_flags = TypeFlags::HAS_NORMALIZABLE_PROJECTION |
TypeFlags::HAS_PROJECTION;
if projection_flags.intersects(self.flags) {
return true;
}
let flags = c.type_flags();
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
if flags.intersects(self.flags) {
true
} else {
c.super_visit_with(self)
}
c.super_visit_with(self)
}
}