]> git.lizzy.rs Git - rust.git/commitdiff
Recycle skolemization counts and add some comments.
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 10 Dec 2014 16:12:48 +0000 (11:12 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 19 Dec 2014 08:29:29 +0000 (03:29 -0500)
src/librustc/middle/infer/higher_ranked/mod.rs
src/librustc/middle/infer/region_inference/mod.rs

index 0a2049bef48f2a97b14dd71cd76936fcd87e853c..d462c223bc65b2174241ac3cf2342353a07b4a35 100644 (file)
@@ -76,7 +76,9 @@ fn higher_ranked_sub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
             // fresh concrete region.
             let (b_prime, skol_map) = {
                 replace_late_bound_regions(self.tcx(), b, |br, _| {
-                    let skol = self.infcx().region_vars.new_skolemized(br);
+                    let skol =
+                        self.infcx().region_vars.new_skolemized(
+                            br, &snapshot.region_vars_snapshot);
                     debug!("Bound region {} skolemized to {}",
                            bound_region_to_string(self.tcx(), "", false, br),
                            skol);
index fef87c920679e5f8b89898e65096dd01e0ac66a6..d34373e66a1e029aceae2923c462f5510d7eaa00 100644 (file)
@@ -226,7 +226,8 @@ pub struct RegionVarBindings<'a, 'tcx: 'a> {
 #[deriving(Show)]
 #[allow(missing_copy_implementations)]
 pub struct RegionSnapshot {
-    length: uint
+    length: uint,
+    skolemization_count: uint,
 }
 
 impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
@@ -254,7 +255,7 @@ pub fn start_snapshot(&self) -> RegionSnapshot {
         let length = self.undo_log.borrow().len();
         debug!("RegionVarBindings: start_snapshot({})", length);
         self.undo_log.borrow_mut().push(OpenSnapshot);
-        RegionSnapshot { length: length }
+        RegionSnapshot { length: length, skolemization_count: self.skolemization_count.get() }
     }
 
     pub fn commit(&self, snapshot: RegionSnapshot) {
@@ -268,6 +269,7 @@ pub fn commit(&self, snapshot: RegionSnapshot) {
         } else {
             (*undo_log)[snapshot.length] = CommitedSnapshot;
         }
+        self.skolemization_count.set(snapshot.skolemization_count);
     }
 
     pub fn rollback_to(&self, snapshot: RegionSnapshot) {
@@ -306,6 +308,7 @@ pub fn rollback_to(&self, snapshot: RegionSnapshot) {
         }
         let c = undo_log.pop().unwrap();
         assert!(c == OpenSnapshot);
+        self.skolemization_count.set(snapshot.skolemization_count);
     }
 
     pub fn num_vars(&self) -> uint {
@@ -324,7 +327,25 @@ pub fn new_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> RegionVid {
         return vid;
     }
 
-    pub fn new_skolemized(&self, br: ty::BoundRegion) -> Region {
+    /// Creates a new skolemized region. Skolemized regions are fresh
+    /// regions used when performing higher-ranked computations. They
+    /// must be used in a very particular way and are never supposed
+    /// to "escape" out into error messages or the code at large.
+    ///
+    /// The idea is to always create a snapshot. Skolemized regions
+    /// can be created in the context of this snapshot, but once the
+    /// snapshot is commited or rolled back, their numbers will be
+    /// recycled, so you must be finished with them. See the extensive
+    /// comments in `higher_ranked.rs` to see how it works (in
+    /// particular, the subtyping comparison).
+    ///
+    /// The `snapshot` argument to this function is not really used;
+    /// it's just there to make it explicit which snapshot bounds the
+    /// skolemized region that results.
+    pub fn new_skolemized(&self, br: ty::BoundRegion, snapshot: &RegionSnapshot) -> Region {
+        assert!(self.in_snapshot());
+        assert!(self.undo_log.borrow()[snapshot.length] == OpenSnapshot);
+
         let sc = self.skolemization_count.get();
         self.skolemization_count.set(sc + 1);
         ReInfer(ReSkolemized(sc, br))