about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2019-02-20 01:15:21 +0000
committervarkor <github@varkor.com>2019-03-05 22:11:04 +0000
commitcbf5d22bcdd8674db1f3945326e4ff8d6b6986c8 (patch)
tree5d890cbc4e7d059c29e117df7fa2bdd8a83e00a6
parent29c272d4edcd1974c2c501a9310acbb30c65fe54 (diff)
downloadrust-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.rs32
-rw-r--r--src/librustc/ty/fold.rs19
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)
     }
 }