]> git.lizzy.rs Git - rust.git/commitdiff
Extract leak check into a distinct subroutine.
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 10 Dec 2014 23:27:04 +0000 (18:27 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 19 Dec 2014 08:29:30 +0000 (03:29 -0500)
src/librustc/middle/infer/higher_ranked/mod.rs

index c1320b6042ab0fb0a016af7cdbfe23a2dc558b66..ef8c2f414acf44221029d0ac38ce3c3897228230 100644 (file)
@@ -84,30 +84,17 @@ fn higher_ranked_sub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
 
             // Presuming type comparison succeeds, we need to check
             // that the skolemized regions do not "leak".
-            let new_vars = self.infcx().region_vars_confined_to_snapshot(snapshot);
-            for (&skol_br, &skol) in skol_map.iter() {
-                let tainted = self.infcx().tainted_regions(snapshot, skol);
-                for tainted_region in tainted.iter() {
-                    // Each skolemized should only be relatable to itself
-                    // or new variables:
-                    match *tainted_region {
-                        ty::ReInfer(ty::ReVar(ref vid)) => {
-                            if new_vars.iter().any(|x| x == vid) { continue; }
-                        }
-                        _ => {
-                            if *tainted_region == skol { continue; }
-                        }
-                    };
-
-                    // A is not as polymorphic as B:
+            match leak_check(self.infcx(), &skol_map, snapshot) {
+                Ok(()) => { }
+                Err((skol_br, tainted_region)) => {
                     if self.a_is_expected() {
                         debug!("Not as polymorphic!");
                         return Err(ty::terr_regions_insufficiently_polymorphic(skol_br,
-                                                                               *tainted_region));
+                                                                               tainted_region));
                     } else {
                         debug!("Overly polymorphic!");
                         return Err(ty::terr_regions_overly_polymorphic(skol_br,
-                                                                       *tainted_region));
+                                                                       tainted_region));
                     }
                 }
             }
@@ -548,3 +535,30 @@ fn skolemize_regions<'a,'tcx,HR>(infcx: &InferCtxt<'a,'tcx>,
         skol
     })
 }
+
+fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
+                       skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
+                       snapshot: &CombinedSnapshot)
+                       -> Result<(),(ty::BoundRegion,ty::Region)>
+{
+    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);
+        for &tainted_region in tainted.iter() {
+            // Each skolemized should only be relatable to itself
+            // or new variables:
+            match tainted_region {
+                ty::ReInfer(ty::ReVar(vid)) => {
+                    if new_vars.iter().any(|&x| x == vid) { continue; }
+                }
+                _ => {
+                    if tainted_region == skol { continue; }
+                }
+            };
+
+            // A is not as polymorphic as B:
+            return Err((skol_br, tainted_region));
+        }
+    }
+    Ok(())
+}