11use crate :: infer:: free_regions:: FreeRegionMap ;
22use crate :: infer:: { GenericKind , InferCtxt } ;
33use crate :: traits:: query:: OutlivesBound ;
4- use rustc_data_structures:: fx:: FxHashMap ;
5- use rustc_hir as hir;
64use rustc_middle:: ty:: { self , ReEarlyBound , ReFree , ReVar , Region } ;
75
86use super :: explicit_outlives_bounds;
@@ -31,9 +29,7 @@ pub struct OutlivesEnvironment<'tcx> {
3129 pub param_env : ty:: ParamEnv < ' tcx > ,
3230 free_region_map : FreeRegionMap < ' tcx > ,
3331
34- // Contains, for each body B that we are checking (that is, the fn
35- // item, but also any nested closures), the set of implied region
36- // bounds that are in scope in that particular body.
32+ // Contains the implied region bounds in scope for our current body.
3733 //
3834 // Example:
3935 //
@@ -43,24 +39,15 @@ pub struct OutlivesEnvironment<'tcx> {
4339 // } // body B0
4440 // ```
4541 //
46- // Here, for body B0, the list would be `[T: 'a]`, because we
42+ // Here, when checking the body B0, the list would be `[T: 'a]`, because we
4743 // infer that `T` must outlive `'a` from the implied bounds on the
4844 // fn declaration.
4945 //
50- // For the body B1, the list would be `[T: 'a, T: 'b]`, because we
46+ // For the body B1 however , the list would be `[T: 'a, T: 'b]`, because we
5147 // also can see that -- within the closure body! -- `T` must
5248 // outlive `'b`. This is not necessarily true outside the closure
5349 // body, since the closure may never be called.
54- //
55- // We collect this map as we descend the tree. We then use the
56- // results when proving outlives obligations like `T: 'x` later
57- // (e.g., if `T: 'x` must be proven within the body B1, then we
58- // know it is true if either `'a: 'x` or `'b: 'x`).
59- region_bound_pairs_map : FxHashMap < hir:: HirId , RegionBoundPairs < ' tcx > > ,
60-
61- // Used to compute `region_bound_pairs_map`: contains the set of
62- // in-scope region-bound pairs thus far.
63- region_bound_pairs_accum : RegionBoundPairs < ' tcx > ,
50+ region_bound_pairs : RegionBoundPairs < ' tcx > ,
6451}
6552
6653/// "Region-bound pairs" tracks outlives relations that are known to
@@ -73,8 +60,7 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
7360 let mut env = OutlivesEnvironment {
7461 param_env,
7562 free_region_map : Default :: default ( ) ,
76- region_bound_pairs_map : Default :: default ( ) ,
77- region_bound_pairs_accum : vec ! [ ] ,
63+ region_bound_pairs : Default :: default ( ) ,
7864 } ;
7965
8066 env. add_outlives_bounds ( None , explicit_outlives_bounds ( param_env) ) ;
@@ -87,62 +73,9 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
8773 & self . free_region_map
8874 }
8975
90- /// Borrows current value of the `region_bound_pairs`.
91- pub fn region_bound_pairs_map ( & self ) -> & FxHashMap < hir:: HirId , RegionBoundPairs < ' tcx > > {
92- & self . region_bound_pairs_map
93- }
94-
95- /// This is a hack to support the old-school regionck, which
96- /// processes region constraints from the main function and the
97- /// closure together. In that context, when we enter a closure, we
98- /// want to be able to "save" the state of the surrounding a
99- /// function. We can then add implied bounds and the like from the
100- /// closure arguments into the environment -- these should only
101- /// apply in the closure body, so once we exit, we invoke
102- /// `pop_snapshot_post_typeck_child` to remove them.
103- ///
104- /// Example:
105- ///
106- /// ```ignore (pseudo-rust)
107- /// fn foo<T>() {
108- /// callback(for<'a> |x: &'a T| {
109- /// // ^^^^^^^ not legal syntax, but probably should be
110- /// // within this closure body, `T: 'a` holds
111- /// })
112- /// }
113- /// ```
114- ///
115- /// This "containment" of closure's effects only works so well. In
116- /// particular, we (intentionally) leak relationships between free
117- /// regions that are created by the closure's bounds. The case
118- /// where this is useful is when you have (e.g.) a closure with a
119- /// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
120- /// case, we want to keep the relationship `'b: 'a` in the
121- /// free-region-map, so that later if we have to take `LUB('b,
122- /// 'a)` we can get the result `'b`.
123- ///
124- /// I have opted to keep **all modifications** to the
125- /// free-region-map, however, and not just those that concern free
126- /// variables bound in the closure. The latter seems more correct,
127- /// but it is not the existing behavior, and I could not find a
128- /// case where the existing behavior went wrong. In any case, it
129- /// seems like it'd be readily fixed if we wanted. There are
130- /// similar leaks around givens that seem equally suspicious, to
131- /// be honest. --nmatsakis
132- pub fn push_snapshot_pre_typeck_child ( & self ) -> usize {
133- self . region_bound_pairs_accum . len ( )
134- }
135-
136- /// See `push_snapshot_pre_typeck_child`.
137- pub fn pop_snapshot_post_typeck_child ( & mut self , len : usize ) {
138- self . region_bound_pairs_accum . truncate ( len) ;
139- }
140-
141- /// Save the current set of region-bound pairs under the given `body_id`.
142- pub fn save_implied_bounds ( & mut self , body_id : hir:: HirId ) {
143- let old =
144- self . region_bound_pairs_map . insert ( body_id, self . region_bound_pairs_accum . clone ( ) ) ;
145- assert ! ( old. is_none( ) ) ;
76+ /// Borrows current `region_bound_pairs`.
77+ pub fn region_bound_pairs ( & self ) -> & RegionBoundPairs < ' tcx > {
78+ & self . region_bound_pairs
14679 }
14780
14881 /// Processes outlives bounds that are known to hold, whether from implied or other sources.
@@ -164,11 +97,10 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
16497 debug ! ( "add_outlives_bounds: outlives_bound={:?}" , outlives_bound) ;
16598 match outlives_bound {
16699 OutlivesBound :: RegionSubParam ( r_a, param_b) => {
167- self . region_bound_pairs_accum . push ( ( r_a, GenericKind :: Param ( param_b) ) ) ;
100+ self . region_bound_pairs . push ( ( r_a, GenericKind :: Param ( param_b) ) ) ;
168101 }
169102 OutlivesBound :: RegionSubProjection ( r_a, projection_b) => {
170- self . region_bound_pairs_accum
171- . push ( ( r_a, GenericKind :: Projection ( projection_b) ) ) ;
103+ self . region_bound_pairs . push ( ( r_a, GenericKind :: Projection ( projection_b) ) ) ;
172104 }
173105 OutlivesBound :: RegionSubRegion ( r_a, r_b) => {
174106 if let ( ReEarlyBound ( _) | ReFree ( _) , ReVar ( vid_b) ) = ( r_a. kind ( ) , r_b. kind ( ) ) {
0 commit comments