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