diff options
| author | varkor <github@varkor.com> | 2019-02-20 01:15:21 +0000 |
|---|---|---|
| committer | varkor <github@varkor.com> | 2019-03-05 22:11:04 +0000 |
| commit | cbf5d22bcdd8674db1f3945326e4ff8d6b6986c8 (patch) | |
| tree | 5d890cbc4e7d059c29e117df7fa2bdd8a83e00a6 | |
| parent | 29c272d4edcd1974c2c501a9310acbb30c65fe54 (diff) | |
| download | rust-cbf5d22bcdd8674db1f3945326e4ff8d6b6986c8.tar.gz rust-cbf5d22bcdd8674db1f3945326e4ff8d6b6986c8.zip | |
Add const type flags
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
| -rw-r--r-- | src/librustc/ty/flags.rs | 32 | ||||
| -rw-r--r-- | src/librustc/ty/fold.rs | 19 |
2 files changed, 34 insertions, 17 deletions
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 2b12dcca93a..64ceb9729ed 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -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), + } } } } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index aa4d1e5ea90..7f77d037bb6 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -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) } } |
