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