@@ -19,7 +19,6 @@ use super::{CombinedSnapshot,
19
19
use super :: combine:: CombineFields ;
20
20
use super :: region_constraints:: { TaintDirections } ;
21
21
22
- use std:: collections:: BTreeMap ;
23
22
use ty:: { self , TyCtxt , Binder , TypeFoldable } ;
24
23
use ty:: error:: TypeError ;
25
24
use ty:: relate:: { Relate , RelateResult , TypeRelation } ;
@@ -200,261 +199,6 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
200
199
Ok ( HrMatchResult { value : a_value } )
201
200
} ) ;
202
201
}
203
-
204
- pub fn higher_ranked_lub < T > ( & mut self , a : & Binder < T > , b : & Binder < T > , a_is_expected : bool )
205
- -> RelateResult < ' tcx , Binder < T > >
206
- where T : Relate < ' tcx >
207
- {
208
- // Start a snapshot so we can examine "all bindings that were
209
- // created as part of this type comparison".
210
- return self . infcx . commit_if_ok ( |snapshot| {
211
- // Instantiate each bound region with a fresh region variable.
212
- let span = self . trace . cause . span ;
213
- let ( a_with_fresh, a_map) =
214
- self . infcx . replace_late_bound_regions_with_fresh_var (
215
- span, HigherRankedType , a) ;
216
- let ( b_with_fresh, _) =
217
- self . infcx . replace_late_bound_regions_with_fresh_var (
218
- span, HigherRankedType , b) ;
219
-
220
- // Collect constraints.
221
- let result0 =
222
- self . lub ( a_is_expected) . relate ( & a_with_fresh, & b_with_fresh) ?;
223
- let result0 =
224
- self . infcx . resolve_type_vars_if_possible ( & result0) ;
225
- debug ! ( "lub result0 = {:?}" , result0) ;
226
-
227
- // Generalize the regions appearing in result0 if possible
228
- let new_vars = self . infcx . region_vars_confined_to_snapshot ( snapshot) ;
229
- let span = self . trace . cause . span ;
230
- let result1 =
231
- fold_regions_in (
232
- self . tcx ( ) ,
233
- & result0,
234
- |r, debruijn| generalize_region ( self . infcx , span, snapshot, debruijn,
235
- & new_vars, & a_map, r) ) ;
236
-
237
- debug ! ( "lub({:?},{:?}) = {:?}" ,
238
- a,
239
- b,
240
- result1) ;
241
-
242
- Ok ( ty:: Binder ( result1) )
243
- } ) ;
244
-
245
- fn generalize_region < ' a , ' gcx , ' tcx > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
246
- span : Span ,
247
- snapshot : & CombinedSnapshot < ' a , ' tcx > ,
248
- debruijn : ty:: DebruijnIndex ,
249
- new_vars : & [ ty:: RegionVid ] ,
250
- a_map : & BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > ,
251
- r0 : ty:: Region < ' tcx > )
252
- -> ty:: Region < ' tcx > {
253
- // Regions that pre-dated the LUB computation stay as they are.
254
- if !is_var_in_set ( new_vars, r0) {
255
- assert ! ( !r0. is_late_bound( ) ) ;
256
- debug ! ( "generalize_region(r0={:?}): not new variable" , r0) ;
257
- return r0;
258
- }
259
-
260
- let tainted = infcx. tainted_regions ( snapshot, r0, TaintDirections :: both ( ) ) ;
261
-
262
- // Variables created during LUB computation which are
263
- // *related* to regions that pre-date the LUB computation
264
- // stay as they are.
265
- if !tainted. iter ( ) . all ( |& r| is_var_in_set ( new_vars, r) ) {
266
- debug ! ( "generalize_region(r0={:?}): \
267
- non-new-variables found in {:?}",
268
- r0, tainted) ;
269
- assert ! ( !r0. is_late_bound( ) ) ;
270
- return r0;
271
- }
272
-
273
- // Otherwise, the variable must be associated with at
274
- // least one of the variables representing bound regions
275
- // in both A and B. Replace the variable with the "first"
276
- // bound region from A that we find it to be associated
277
- // with.
278
- for ( a_br, a_r) in a_map {
279
- if tainted. iter ( ) . any ( |x| x == a_r) {
280
- debug ! ( "generalize_region(r0={:?}): \
281
- replacing with {:?}, tainted={:?}",
282
- r0, * a_br, tainted) ;
283
- return infcx. tcx . mk_region ( ty:: ReLateBound ( debruijn, * a_br) ) ;
284
- }
285
- }
286
-
287
- span_bug ! (
288
- span,
289
- "region {:?} is not associated with any bound region from A!" ,
290
- r0)
291
- }
292
- }
293
-
294
- pub fn higher_ranked_glb < T > ( & mut self , a : & Binder < T > , b : & Binder < T > , a_is_expected : bool )
295
- -> RelateResult < ' tcx , Binder < T > >
296
- where T : Relate < ' tcx >
297
- {
298
- debug ! ( "higher_ranked_glb({:?}, {:?})" ,
299
- a, b) ;
300
-
301
- // Make a snapshot so we can examine "all bindings that were
302
- // created as part of this type comparison".
303
- return self . infcx . commit_if_ok ( |snapshot| {
304
- // Instantiate each bound region with a fresh region variable.
305
- let ( a_with_fresh, a_map) =
306
- self . infcx . replace_late_bound_regions_with_fresh_var (
307
- self . trace . cause . span , HigherRankedType , a) ;
308
- let ( b_with_fresh, b_map) =
309
- self . infcx . replace_late_bound_regions_with_fresh_var (
310
- self . trace . cause . span , HigherRankedType , b) ;
311
- let a_vars = var_ids ( self , & a_map) ;
312
- let b_vars = var_ids ( self , & b_map) ;
313
-
314
- // Collect constraints.
315
- let result0 =
316
- self . glb ( a_is_expected) . relate ( & a_with_fresh, & b_with_fresh) ?;
317
- let result0 =
318
- self . infcx . resolve_type_vars_if_possible ( & result0) ;
319
- debug ! ( "glb result0 = {:?}" , result0) ;
320
-
321
- // Generalize the regions appearing in result0 if possible
322
- let new_vars = self . infcx . region_vars_confined_to_snapshot ( snapshot) ;
323
- let span = self . trace . cause . span ;
324
- let result1 =
325
- fold_regions_in (
326
- self . tcx ( ) ,
327
- & result0,
328
- |r, debruijn| generalize_region ( self . infcx , span, snapshot, debruijn,
329
- & new_vars,
330
- & a_map, & a_vars, & b_vars,
331
- r) ) ;
332
-
333
- debug ! ( "glb({:?},{:?}) = {:?}" ,
334
- a,
335
- b,
336
- result1) ;
337
-
338
- Ok ( ty:: Binder ( result1) )
339
- } ) ;
340
-
341
- fn generalize_region < ' a , ' gcx , ' tcx > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
342
- span : Span ,
343
- snapshot : & CombinedSnapshot < ' a , ' tcx > ,
344
- debruijn : ty:: DebruijnIndex ,
345
- new_vars : & [ ty:: RegionVid ] ,
346
- a_map : & BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > ,
347
- a_vars : & [ ty:: RegionVid ] ,
348
- b_vars : & [ ty:: RegionVid ] ,
349
- r0 : ty:: Region < ' tcx > )
350
- -> ty:: Region < ' tcx > {
351
- if !is_var_in_set ( new_vars, r0) {
352
- assert ! ( !r0. is_late_bound( ) ) ;
353
- return r0;
354
- }
355
-
356
- let tainted = infcx. tainted_regions ( snapshot, r0, TaintDirections :: both ( ) ) ;
357
-
358
- let mut a_r = None ;
359
- let mut b_r = None ;
360
- let mut only_new_vars = true ;
361
- for r in & tainted {
362
- if is_var_in_set ( a_vars, * r) {
363
- if a_r. is_some ( ) {
364
- return fresh_bound_variable ( infcx, debruijn) ;
365
- } else {
366
- a_r = Some ( * r) ;
367
- }
368
- } else if is_var_in_set ( b_vars, * r) {
369
- if b_r. is_some ( ) {
370
- return fresh_bound_variable ( infcx, debruijn) ;
371
- } else {
372
- b_r = Some ( * r) ;
373
- }
374
- } else if !is_var_in_set ( new_vars, * r) {
375
- only_new_vars = false ;
376
- }
377
- }
378
-
379
- // NB---I do not believe this algorithm computes
380
- // (necessarily) the GLB. As written it can
381
- // spuriously fail. In particular, if there is a case
382
- // like: |fn(&a)| and fn(fn(&b)), where a and b are
383
- // free, it will return fn(&c) where c = GLB(a,b). If
384
- // however this GLB is not defined, then the result is
385
- // an error, even though something like
386
- // "fn<X>(fn(&X))" where X is bound would be a
387
- // subtype of both of those.
388
- //
389
- // The problem is that if we were to return a bound
390
- // variable, we'd be computing a lower-bound, but not
391
- // necessarily the *greatest* lower-bound.
392
- //
393
- // Unfortunately, this problem is non-trivial to solve,
394
- // because we do not know at the time of computing the GLB
395
- // whether a GLB(a,b) exists or not, because we haven't
396
- // run region inference (or indeed, even fully computed
397
- // the region hierarchy!). The current algorithm seems to
398
- // works ok in practice.
399
-
400
- if a_r. is_some ( ) && b_r. is_some ( ) && only_new_vars {
401
- // Related to exactly one bound variable from each fn:
402
- return rev_lookup ( infcx, span, a_map, a_r. unwrap ( ) ) ;
403
- } else if a_r. is_none ( ) && b_r. is_none ( ) {
404
- // Not related to bound variables from either fn:
405
- assert ! ( !r0. is_late_bound( ) ) ;
406
- return r0;
407
- } else {
408
- // Other:
409
- return fresh_bound_variable ( infcx, debruijn) ;
410
- }
411
- }
412
-
413
- fn rev_lookup < ' a , ' gcx , ' tcx > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
414
- span : Span ,
415
- a_map : & BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > ,
416
- r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx >
417
- {
418
- for ( a_br, a_r) in a_map {
419
- if * a_r == r {
420
- return infcx. tcx . mk_region ( ty:: ReLateBound ( ty:: DebruijnIndex :: new ( 1 ) , * a_br) ) ;
421
- }
422
- }
423
- span_bug ! (
424
- span,
425
- "could not find original bound region for {:?}" ,
426
- r) ;
427
- }
428
-
429
- fn fresh_bound_variable < ' a , ' gcx , ' tcx > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
430
- debruijn : ty:: DebruijnIndex )
431
- -> ty:: Region < ' tcx > {
432
- infcx. borrow_region_constraints ( ) . new_bound ( infcx. tcx , debruijn)
433
- }
434
- }
435
- }
436
-
437
- fn var_ids < ' a , ' gcx , ' tcx > ( fields : & CombineFields < ' a , ' gcx , ' tcx > ,
438
- map : & BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > )
439
- -> Vec < ty:: RegionVid > {
440
- map. iter ( )
441
- . map ( |( _, & r) | match * r {
442
- ty:: ReVar ( r) => { r }
443
- _ => {
444
- span_bug ! (
445
- fields. trace. cause. span,
446
- "found non-region-vid: {:?}" ,
447
- r) ;
448
- }
449
- } )
450
- . collect ( )
451
- }
452
-
453
- fn is_var_in_set ( new_vars : & [ ty:: RegionVid ] , r : ty:: Region ) -> bool {
454
- match * r {
455
- ty:: ReVar ( ref v) => new_vars. iter ( ) . any ( |x| x == v) ,
456
- _ => false
457
- }
458
202
}
459
203
460
204
fn fold_regions_in < ' a , ' gcx , ' tcx , T , F > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
0 commit comments