Add const type flags
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
This commit is contained in:
parent
29c272d4ed
commit
cbf5d22bcd
2 changed files with 34 additions and 17 deletions
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue