about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-12-12 14:55:07 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-12-19 03:29:30 -0500
commit4f34524fcbd9672e2fd6bb27e657da2c26051fdf (patch)
tree1f8641b18cec69d1b81403e4f6a98988cc6b305e /src
parent1205fd88df2b87c682f2e98e30ba9e2d8d44d656 (diff)
downloadrust-4f34524fcbd9672e2fd6bb27e657da2c26051fdf.tar.gz
rust-4f34524fcbd9672e2fd6bb27e657da2c26051fdf.zip
Move `leak_check` into its own method, and ensure that all higher-ranked code is in
`higher_ranked.rs`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs53
-rw-r--r--src/librustc/middle/infer/mod.rs23
2 files changed, 60 insertions, 16 deletions
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index dcc365fad18..ca4a6b28c2a 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -11,7 +11,7 @@
 //! Helper routines for higher-ranked things. See the `doc` module at
 //! the end of the file for details.
 
-use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType};
+use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType, SkolemizationMap};
 use super::combine::{Combine, Combineable};
 
 use middle::ty::{mod, Binder};
@@ -81,7 +81,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
 
             // Presuming type comparison succeeds, we need to check
             // that the skolemized regions do not "leak".
-            match leak_check(self.infcx(), &skol_map, snapshot) {
+            match self.infcx().leak_check(&skol_map, snapshot) {
                 Ok(()) => { }
                 Err((skol_br, tainted_region)) => {
                     if self.a_is_expected() {
@@ -455,11 +455,47 @@ impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
     }
 }
 
-fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
-                       skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
-                       snapshot: &CombinedSnapshot)
-                       -> Result<(),(ty::BoundRegion,ty::Region)>
+pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
+                                               binder: &ty::Binder<T>,
+                                               snapshot: &CombinedSnapshot)
+                                               -> (T, SkolemizationMap)
+    where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
+    /*!
+     * Replace all regions bound by `binder` with skolemized regions and
+     * return a map indicating which bound-region was replaced with what
+     * skolemized region. This is the first step of checking subtyping
+     * when higher-ranked things are involved. See `doc.rs` for more details.
+     */
+
+    let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br, _| {
+        infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
+    });
+
+    debug!("skolemize_bound_regions(binder={}, result={}, map={})",
+           binder.repr(infcx.tcx),
+           result.repr(infcx.tcx),
+           map.repr(infcx.tcx));
+
+    (result, map)
+}
+
+pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
+                           skol_map: &SkolemizationMap,
+                           snapshot: &CombinedSnapshot)
+                           -> Result<(),(ty::BoundRegion,ty::Region)>
+{
+    /*!
+     * Searches the region constriants created since `snapshot` was started
+     * and checks to determine whether any of the skolemized regions created
+     * in `skol_map` would "escape" -- meaning that they are related to
+     * other regions in some way. If so, the higher-ranked subtyping doesn't
+     * hold. See `doc.rs` for more details.
+     */
+
+    debug!("leak_check: skol_map={}",
+           skol_map.repr(infcx.tcx));
+
     let new_vars = infcx.region_vars_confined_to_snapshot(snapshot);
     for (&skol_br, &skol) in skol_map.iter() {
         let tainted = infcx.tainted_regions(snapshot, skol);
@@ -475,6 +511,11 @@ fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                 }
             };
 
+            debug!("{} (which replaced {}) is tainted by {}",
+                   skol.repr(infcx.tcx),
+                   skol_br.repr(infcx.tcx),
+                   tainted_region.repr(infcx.tcx));
+
             // A is not as polymorphic as B:
             return Err((skol_br, tainted_region));
         }
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index edd5c8b854e..0dfae4b882b 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -52,7 +52,7 @@ pub mod doc;
 pub mod equate;
 pub mod error_reporting;
 pub mod glb;
-pub mod higher_ranked;
+mod higher_ranked;
 pub mod lattice;
 pub mod lub;
 pub mod region_inference;
@@ -90,7 +90,7 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
         RegionVarBindings<'a, 'tcx>,
 }
 
-/// A map returned by `skolemize_bound_regions()` indicating the skolemized
+/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
 /// region that each late-bound region was replaced with.
 pub type SkolemizationMap = FnvHashMap<ty::BoundRegion,ty::Region>;
 
@@ -709,16 +709,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                            -> (T, SkolemizationMap)
         where T : TypeFoldable<'tcx> + Repr<'tcx>
     {
-        let (result, map) = replace_late_bound_regions(self.tcx, value, |br, _| {
-            self.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
-        });
+        /*! See `higher_ranked::skolemize_late_bound_regions` */
 
-        debug!("skolemize_bound_regions(value={}, result={}, map={})",
-               value.repr(self.tcx),
-               result.repr(self.tcx),
-               map.repr(self.tcx));
+        higher_ranked::skolemize_late_bound_regions(self, value, snapshot)
+    }
+
+    pub fn leak_check(&self,
+                      skol_map: &SkolemizationMap,
+                      snapshot: &CombinedSnapshot)
+                      -> Result<(),(ty::BoundRegion,ty::Region)>
+    {
+        /*! See `higher_ranked::leak_check` */
 
-        (result, map)
+        higher_ranked::leak_check(self, skol_map, snapshot)
     }
 
     pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {