15
15
//! `TransitiveRelation` type and use that to decide when one free
16
16
//! region outlives another and so forth.
17
17
18
+ use infer:: outlives:: free_region_map:: FreeRegionMap ;
18
19
use hir:: def_id:: DefId ;
19
20
use middle:: region;
20
- use ty:: { self , Lift , TyCtxt , Region } ;
21
- use rustc_data_structures:: transitive_relation:: TransitiveRelation ;
21
+ use ty:: { self , TyCtxt , Region } ;
22
22
23
23
/// Combines a `region::ScopeTree` (which governs relationships between
24
24
/// scopes) and a `FreeRegionMap` (which governs relationships between
@@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
103
103
ty:: ReStatic => true ,
104
104
ty:: ReEarlyBound ( _) | ty:: ReFree ( _) => {
105
105
let re_static = self . tcx . mk_region ( ty:: ReStatic ) ;
106
- self . free_regions . relation . contains ( & re_static, & super_region)
106
+ self . free_regions . sub_free_regions ( & re_static, & super_region)
107
107
}
108
108
_ => false
109
109
}
@@ -117,128 +117,3 @@ impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
117
117
}
118
118
}
119
119
120
- #[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
121
- pub struct FreeRegionMap < ' tcx > {
122
- // Stores the relation `a < b`, where `a` and `b` are regions.
123
- //
124
- // Invariant: only free regions like `'x` or `'static` are stored
125
- // in this relation, not scopes.
126
- relation : TransitiveRelation < Region < ' tcx > >
127
- }
128
-
129
- impl < ' tcx > FreeRegionMap < ' tcx > {
130
- pub fn new ( ) -> Self {
131
- FreeRegionMap { relation : TransitiveRelation :: new ( ) }
132
- }
133
-
134
- pub fn is_empty ( & self ) -> bool {
135
- self . relation . is_empty ( )
136
- }
137
-
138
- pub fn relate_free_regions_from_predicates ( & mut self ,
139
- predicates : & [ ty:: Predicate < ' tcx > ] ) {
140
- debug ! ( "relate_free_regions_from_predicates(predicates={:?})" , predicates) ;
141
- for predicate in predicates {
142
- match * predicate {
143
- ty:: Predicate :: Projection ( ..) |
144
- ty:: Predicate :: Trait ( ..) |
145
- ty:: Predicate :: Equate ( ..) |
146
- ty:: Predicate :: Subtype ( ..) |
147
- ty:: Predicate :: WellFormed ( ..) |
148
- ty:: Predicate :: ObjectSafe ( ..) |
149
- ty:: Predicate :: ClosureKind ( ..) |
150
- ty:: Predicate :: TypeOutlives ( ..) |
151
- ty:: Predicate :: ConstEvaluatable ( ..) => {
152
- // No region bounds here
153
- }
154
- ty:: Predicate :: RegionOutlives ( ty:: Binder ( ty:: OutlivesPredicate ( r_a, r_b) ) ) => {
155
- self . relate_regions ( r_b, r_a) ;
156
- }
157
- }
158
- }
159
- }
160
-
161
- /// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
162
- /// (with the exception that `'static: 'x` is not notable)
163
- pub fn relate_regions ( & mut self , sub : Region < ' tcx > , sup : Region < ' tcx > ) {
164
- debug ! ( "relate_regions(sub={:?}, sup={:?})" , sub, sup) ;
165
- if is_free_or_static ( sub) && is_free ( sup) {
166
- self . relation . add ( sub, sup)
167
- }
168
- }
169
-
170
- /// Tests whether `r_a <= sup`. Both must be free regions or
171
- /// `'static`.
172
- pub fn sub_free_regions < ' a , ' gcx > ( & self ,
173
- r_a : Region < ' tcx > ,
174
- r_b : Region < ' tcx > )
175
- -> bool {
176
- assert ! ( is_free_or_static( r_a) && is_free_or_static( r_b) ) ;
177
- if let ty:: ReStatic = r_b {
178
- true // `'a <= 'static` is just always true, and not stored in the relation explicitly
179
- } else {
180
- r_a == r_b || self . relation . contains ( & r_a, & r_b)
181
- }
182
- }
183
-
184
- /// Compute the least-upper-bound of two free regions. In some
185
- /// cases, this is more conservative than necessary, in order to
186
- /// avoid making arbitrary choices. See
187
- /// `TransitiveRelation::postdom_upper_bound` for more details.
188
- pub fn lub_free_regions < ' a , ' gcx > ( & self ,
189
- tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
190
- r_a : Region < ' tcx > ,
191
- r_b : Region < ' tcx > )
192
- -> Region < ' tcx > {
193
- debug ! ( "lub_free_regions(r_a={:?}, r_b={:?})" , r_a, r_b) ;
194
- assert ! ( is_free( r_a) ) ;
195
- assert ! ( is_free( r_b) ) ;
196
- let result = if r_a == r_b { r_a } else {
197
- match self . relation . postdom_upper_bound ( & r_a, & r_b) {
198
- None => tcx. mk_region ( ty:: ReStatic ) ,
199
- Some ( r) => * r,
200
- }
201
- } ;
202
- debug ! ( "lub_free_regions(r_a={:?}, r_b={:?}) = {:?}" , r_a, r_b, result) ;
203
- result
204
- }
205
-
206
- /// Returns all regions that are known to outlive `r_a`. For
207
- /// example, in a function:
208
- ///
209
- /// ```
210
- /// fn foo<'a, 'b: 'a, 'c: 'b>() { .. }
211
- /// ```
212
- ///
213
- /// if `r_a` represents `'a`, this function would return `{'b, 'c}`.
214
- pub fn regions_that_outlive < ' a , ' gcx > ( & self , r_a : Region < ' tcx > ) -> Vec < & Region < ' tcx > > {
215
- assert ! ( is_free( r_a) || * r_a == ty:: ReStatic ) ;
216
- self . relation . greater_than ( & r_a)
217
- }
218
- }
219
-
220
- fn is_free ( r : Region ) -> bool {
221
- match * r {
222
- ty:: ReEarlyBound ( _) | ty:: ReFree ( _) => true ,
223
- _ => false
224
- }
225
- }
226
-
227
- fn is_free_or_static ( r : Region ) -> bool {
228
- match * r {
229
- ty:: ReStatic => true ,
230
- _ => is_free ( r) ,
231
- }
232
- }
233
-
234
- impl_stable_hash_for ! ( struct FreeRegionMap <' tcx> {
235
- relation
236
- } ) ;
237
-
238
- impl < ' a , ' tcx > Lift < ' tcx > for FreeRegionMap < ' a > {
239
- type Lifted = FreeRegionMap < ' tcx > ;
240
- fn lift_to_tcx < ' b , ' gcx > ( & self , tcx : TyCtxt < ' b , ' gcx , ' tcx > ) -> Option < FreeRegionMap < ' tcx > > {
241
- self . relation . maybe_map ( |& fr| fr. lift_to_tcx ( tcx) )
242
- . map ( |relation| FreeRegionMap { relation } )
243
- }
244
- }
0 commit comments