about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-07-15 07:23:28 -0400
committerSean Griffin <sean@seantheprogrammer.com>2018-03-01 08:04:26 -0700
commitd4df52cacbee5d95e912a43188192a5054d36b4f (patch)
treecb60854e691ae24e589b56834ac4cba8b38b92e5
parente7efce23618adcc9c960e1518d00883da8a8c444 (diff)
downloadrust-d4df52cacbee5d95e912a43188192a5054d36b4f.tar.gz
rust-d4df52cacbee5d95e912a43188192a5054d36b4f.zip
introduce `UniverseIndex` into `ParamEnv`
Always using root environment for now.
-rw-r--r--src/librustc/ich/impls_ty.rs10
-rw-r--r--src/librustc/traits/mod.rs7
-rw-r--r--src/librustc/ty/mod.rs25
-rw-r--r--src/librustc/ty/structural_impls.rs26
-rw-r--r--src/librustc/ty/util.rs7
-rw-r--r--src/librustc_typeck/check/compare_method.rs3
6 files changed, 66 insertions, 12 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 71a57dbf32f..7b2cfa0a3ff 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -870,6 +870,7 @@ for ty::steal::Steal<T>
 
 impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
     caller_bounds,
+    universe,
     reveal
 });
 
@@ -1039,3 +1040,12 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContex
         nested.hash_stable(hcx, hasher);
     }
 }
+
+impl<'gcx> HashStable<StableHashingContext<'gcx>>
+for ty::UniverseIndex {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hasher: &mut StableHasher<W>) {
+        self.depth().hash_stable(hcx, hasher);
+    }
+}
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 027ad4174bd..76d3c7f1506 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -546,7 +546,8 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            predicates);
 
     let elaborated_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
-                                           unnormalized_env.reveal);
+                                           unnormalized_env.reveal,
+                                           unnormalized_env.universe);
 
     tcx.infer_ctxt().enter(|infcx| {
         // FIXME. We should really... do something with these region
@@ -620,7 +621,9 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         debug!("normalize_param_env_or_error: resolved predicates={:?}",
                predicates);
 
-        ty::ParamEnv::new(tcx.intern_predicates(&predicates), unnormalized_env.reveal)
+        ty::ParamEnv::new(tcx.intern_predicates(&predicates),
+                          unnormalized_env.reveal,
+                          unnormalized_env.universe)
     })
 }
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 26fcd5c3110..856c53d19c9 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1348,9 +1348,7 @@ pub struct UniverseIndex(u32);
 impl UniverseIndex {
     /// The root universe, where things that the user defined are
     /// visible.
-    pub fn root() -> UniverseIndex {
-        UniverseIndex(0)
-    }
+    pub const ROOT: UniverseIndex = UniverseIndex(0);
 
     /// A "subuniverse" corresponds to being inside a `forall` quantifier.
     /// So, for example, suppose we have this type in universe `U`:
@@ -1366,6 +1364,13 @@ impl UniverseIndex {
     pub fn subuniverse(self) -> UniverseIndex {
         UniverseIndex(self.0 + 1)
     }
+
+    /// Gets the "depth" of this universe in the universe tree. This
+    /// is not really useful except for e.g. the `HashStable`
+    /// implementation
+    pub fn depth(&self) -> u32 {
+        self.0
+    }
 }
 
 /// When type checking, we use the `ParamEnv` to track
@@ -1382,6 +1387,17 @@ pub struct ParamEnv<'tcx> {
     /// want `Reveal::All` -- note that this is always paired with an
     /// empty environment. To get that, use `ParamEnv::reveal()`.
     pub reveal: traits::Reveal,
+
+    /// What is the innermost universe we have created? Starts out as
+    /// `UniverseIndex::root()` but grows from there as we enter
+    /// universal quantifiers.
+    ///
+    /// NB: At present, we exclude the universal quantifiers on the
+    /// item we are type-checking, and just consider those names as
+    /// part of the root universe. So this would only get incremented
+    /// when we enter into a higher-ranked (`for<..>`) type or trait
+    /// bound.
+    pub universe: UniverseIndex,
 }
 
 impl<'tcx> ParamEnv<'tcx> {
@@ -2657,7 +2673,8 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // sure that this will succeed without errors anyway.
 
     let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates),
-                                             traits::Reveal::UserFacing);
+                                             traits::Reveal::UserFacing,
+                                             ty::UniverseIndex::ROOT);
 
     let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
         tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 0dc1338fff8..3a1ad8db9c2 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -405,6 +405,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
         tcx.lift(&self.caller_bounds).map(|caller_bounds| {
             ty::ParamEnv {
                 reveal: self.reveal,
+                universe: self.universe,
                 caller_bounds,
             }
         })
@@ -733,8 +734,29 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
     }
 }
 
-BraceStructTypeFoldableImpl! {
-    impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds }
+impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> {
+    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+        ty::ParamEnv {
+            reveal: self.reveal,
+            caller_bounds: self.caller_bounds.fold_with(folder),
+            universe: self.universe.fold_with(folder),
+        }
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        let &ty::ParamEnv { reveal: _, ref universe, ref caller_bounds } = self;
+        universe.super_visit_with(visitor) || caller_bounds.super_visit_with(visitor)
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for ty::UniverseIndex {
+    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+        *self
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
+        false
+    }
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>> {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 110808919e9..44771444c8a 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -153,14 +153,15 @@ impl<'tcx> ty::ParamEnv<'tcx> {
     /// Construct a trait environment suitable for contexts where
     /// there are no where clauses in scope.
     pub fn empty(reveal: Reveal) -> Self {
-        Self::new(ty::Slice::empty(), reveal)
+        Self::new(ty::Slice::empty(), reveal, ty::UniverseIndex::ROOT)
     }
 
     /// Construct a trait environment with the given set of predicates.
     pub fn new(caller_bounds: &'tcx ty::Slice<ty::Predicate<'tcx>>,
-               reveal: Reveal)
+               reveal: Reveal,
+               universe: ty::UniverseIndex)
                -> Self {
-        ty::ParamEnv { caller_bounds, reveal }
+        ty::ParamEnv { caller_bounds, reveal, universe }
     }
 
     /// Returns a new parameter environment with the same clauses, but
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 4c10f28eb8e..d0419382bc3 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -218,7 +218,8 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // the new hybrid bounds we computed.
     let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_node_id);
     let param_env = ty::ParamEnv::new(tcx.intern_predicates(&hybrid_preds.predicates),
-                                      Reveal::UserFacing);
+                                      Reveal::UserFacing,
+                                      ty::UniverseIndex::ROOT);
     let param_env = traits::normalize_param_env_or_error(tcx,
                                                          impl_m.def_id,
                                                          param_env,