1
1
use crate :: infer:: free_regions:: FreeRegionMap ;
2
2
use crate :: infer:: { GenericKind , InferCtxt } ;
3
3
use crate :: traits:: query:: OutlivesBound ;
4
- use rustc_data_structures:: fx:: FxHashMap ;
5
- use rustc_hir as hir;
6
4
use rustc_middle:: ty:: { self , ReEarlyBound , ReFree , ReVar , Region } ;
7
5
8
6
use super :: explicit_outlives_bounds;
@@ -31,9 +29,7 @@ pub struct OutlivesEnvironment<'tcx> {
31
29
pub param_env : ty:: ParamEnv < ' tcx > ,
32
30
free_region_map : FreeRegionMap < ' tcx > ,
33
31
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.
37
33
//
38
34
// Example:
39
35
//
@@ -43,24 +39,15 @@ pub struct OutlivesEnvironment<'tcx> {
43
39
// } // body B0
44
40
// ```
45
41
//
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
47
43
// infer that `T` must outlive `'a` from the implied bounds on the
48
44
// fn declaration.
49
45
//
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
51
47
// also can see that -- within the closure body! -- `T` must
52
48
// outlive `'b`. This is not necessarily true outside the closure
53
49
// 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 > ,
64
51
}
65
52
66
53
/// "Region-bound pairs" tracks outlives relations that are known to
@@ -73,8 +60,7 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
73
60
let mut env = OutlivesEnvironment {
74
61
param_env,
75
62
free_region_map : Default :: default ( ) ,
76
- region_bound_pairs_map : Default :: default ( ) ,
77
- region_bound_pairs_accum : vec ! [ ] ,
63
+ region_bound_pairs : Default :: default ( ) ,
78
64
} ;
79
65
80
66
env. add_outlives_bounds ( None , explicit_outlives_bounds ( param_env) ) ;
@@ -87,62 +73,9 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
87
73
& self . free_region_map
88
74
}
89
75
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
146
79
}
147
80
148
81
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
@@ -164,11 +97,10 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
164
97
debug ! ( "add_outlives_bounds: outlives_bound={:?}" , outlives_bound) ;
165
98
match outlives_bound {
166
99
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) ) ) ;
168
101
}
169
102
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) ) ) ;
172
104
}
173
105
OutlivesBound :: RegionSubRegion ( r_a, r_b) => {
174
106
if let ( ReEarlyBound ( _) | ReFree ( _) , ReVar ( vid_b) ) = ( r_a. kind ( ) , r_b. kind ( ) ) {
0 commit comments