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