@@ -89,6 +89,52 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
8989 self . free_region_map
9090 }
9191
92+ /// This is a hack to support the old-skool regionck, which
93+ /// processes region constraints from the main function and the
94+ /// closure together. In that context, when we enter a closure, we
95+ /// want to be able to "save" the state of the surrounding a
96+ /// function. We can then add implied bounds and the like from the
97+ /// closure arguments into the environment -- these should only
98+ /// apply in the closure body, so once we exit, we invoke
99+ /// `pop_snapshot_post_closure` to remove them.
100+ ///
101+ /// Example:
102+ ///
103+ /// ```
104+ /// fn foo<T>() {
105+ /// callback(for<'a> |x: &'a T| {
106+ /// // ^^^^^^^ not legal syntax, but probably should be
107+ /// // within this closure body, `T: 'a` holds
108+ /// })
109+ /// }
110+ /// ```
111+ ///
112+ /// This "containment" of closure's effects only works so well. In
113+ /// particular, we (intentionally) leak relationships between free
114+ /// regions that are created by the closure's bounds. The case
115+ /// where this is useful is when you have (e.g.) a closure with a
116+ /// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
117+ /// case, we want to keep the relationship `'b: 'a` in the
118+ /// free-region-map, so that later if we have to take `LUB('b,
119+ /// 'a)` we can get the result `'b`.
120+ ///
121+ /// I have opted to keep **all modifications** to the
122+ /// free-region-map, however, and not just those that concern free
123+ /// variables bound in the closure. The latter seems more correct,
124+ /// but it is not the existing behavior, and I could not find a
125+ /// case where the existing behavior went wrong. In any case, it
126+ /// seems like it'd be readily fixed if we wanted. There are
127+ /// similar leaks around givens that seem equally suspicious, to
128+ /// be honest. --nmatsakis
129+ pub fn push_snapshot_pre_closure ( & self ) -> usize {
130+ self . region_bound_pairs . len ( )
131+ }
132+
133+ /// See `push_snapshot_pre_closure`.
134+ pub fn pop_snapshot_post_closure ( & mut self , len : usize ) {
135+ self . region_bound_pairs . truncate ( len) ;
136+ }
137+
92138 /// This method adds "implied bounds" into the outlives environment.
93139 /// Implied bounds are outlives relationships that we can deduce
94140 /// on the basis that certain types must be well-formed -- these are
0 commit comments