diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-12-10 11:12:48 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-12-19 03:29:29 -0500 |
| commit | ff35eeb80a30ffbe3bcc334ed8accb97937676f4 (patch) | |
| tree | 73d66fbf1d4336aebe395f34e728fb7d425f778f | |
| parent | 7be059ffcd640096911b62b9135d2ffbf3a05abc (diff) | |
| download | rust-ff35eeb80a30ffbe3bcc334ed8accb97937676f4.tar.gz rust-ff35eeb80a30ffbe3bcc334ed8accb97937676f4.zip | |
Recycle skolemization counts and add some comments.
| -rw-r--r-- | src/librustc/middle/infer/higher_ranked/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/infer/region_inference/mod.rs | 27 |
2 files changed, 27 insertions, 4 deletions
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 0a2049bef48..d462c223bc6 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -76,7 +76,9 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C // 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); diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index fef87c92067..d34373e66a1 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -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 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { 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 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } else { (*undo_log)[snapshot.length] = CommitedSnapshot; } + self.skolemization_count.set(snapshot.skolemization_count); } pub fn rollback_to(&self, snapshot: RegionSnapshot) { @@ -306,6 +308,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } 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 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { 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)) |
