@@ -82,6 +82,16 @@ pub enum RegionResolutionError<'tcx> {
82
82
Region < ' tcx > ,
83
83
) ,
84
84
85
+ /// Indicates a `'b: 'a` constraint where `'a` is in a universe that
86
+ /// cannot name the placeholder `'b`
87
+ UpperBoundUniverseConflict (
88
+ RegionVid ,
89
+ RegionVariableOrigin ,
90
+ ty:: UniverseIndex , // the universe index of the region variable
91
+ SubregionOrigin < ' tcx > , // cause of the constraint
92
+ Region < ' tcx > , // the placeholder `'b`
93
+ ) ,
94
+
85
95
/// Indicates a failure of a `MemberConstraint`. These arise during
86
96
/// impl trait processing explicitly -- basically, the impl trait's hidden type
87
97
/// included some region that it was not supposed to.
@@ -149,7 +159,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
149
159
fn construct_var_data ( & self , tcx : TyCtxt < ' tcx > ) -> LexicalRegionResolutions < ' tcx > {
150
160
LexicalRegionResolutions {
151
161
error_region : tcx. lifetimes . re_static ,
152
- values : IndexVec :: from_elem_n ( VarValue :: Value ( tcx. lifetimes . re_empty ) , self . num_vars ( ) ) ,
162
+ values : IndexVec :: from_fn_n (
163
+ |vid| {
164
+ let vid_universe = self . var_infos [ vid] . universe ;
165
+ let re_empty = tcx. mk_region ( ty:: ReEmpty ( vid_universe) ) ;
166
+ VarValue :: Value ( re_empty)
167
+ } ,
168
+ self . num_vars ( ) ,
169
+ ) ,
153
170
}
154
171
}
155
172
@@ -381,8 +398,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
381
398
// This is a specialized version of the `lub_concrete_regions`
382
399
// check below for a common case, here purely as an
383
400
// optimization.
384
- if let ReEmpty = a_region {
385
- return false ;
401
+ let b_universe = self . var_infos [ b_vid] . universe ;
402
+ if let ReEmpty ( a_universe) = a_region {
403
+ if * a_universe == b_universe {
404
+ return false ;
405
+ }
386
406
}
387
407
388
408
let mut lub = self . lub_concrete_regions ( a_region, cur_region) ;
@@ -399,7 +419,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
399
419
// tighter bound than `'static`.
400
420
//
401
421
// (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.)
402
- let b_universe = self . var_infos [ b_vid] . universe ;
403
422
if let ty:: RePlaceholder ( p) = lub {
404
423
if b_universe. cannot_name ( p. universe ) {
405
424
lub = self . tcx ( ) . lifetimes . re_static ;
@@ -445,7 +464,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
445
464
self . lub_concrete_regions ( a, b) == b
446
465
}
447
466
448
- /// Returns the smallest region `c` such that `a <= c` and `b <= c`.
467
+ /// Returns the least-upper-bound of `a` and `b`; i.e., the
468
+ /// smallest region `c` such that `a <= c` and `b <= c`.
469
+ ///
470
+ /// Neither `a` nor `b` may be an inference variable (hence the
471
+ /// term "concrete regions").
449
472
fn lub_concrete_regions ( & self , a : Region < ' tcx > , b : Region < ' tcx > ) -> Region < ' tcx > {
450
473
let r = match ( a, b) {
451
474
( & ty:: ReClosureBound ( ..) , _)
@@ -457,14 +480,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
457
480
bug ! ( "cannot relate region: LUB({:?}, {:?})" , a, b) ;
458
481
}
459
482
460
- ( r @ & ReStatic , _) | ( _, r @ & ReStatic ) => {
461
- r // nothing lives longer than static
462
- }
463
-
464
- ( & ReEmpty , r) | ( r, & ReEmpty ) => {
465
- r // everything lives longer than empty
466
- }
467
-
468
483
( & ReVar ( v_id) , _) | ( _, & ReVar ( v_id) ) => {
469
484
span_bug ! (
470
485
self . var_infos[ v_id] . origin. span( ) ,
@@ -475,6 +490,41 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
475
490
) ;
476
491
}
477
492
493
+ ( & ReStatic , _) | ( _, & ReStatic ) => {
494
+ // nothing lives longer than static
495
+ self . tcx ( ) . lifetimes . re_static
496
+ }
497
+
498
+ ( & ReEmpty ( _) , r @ ReEarlyBound ( _) )
499
+ | ( r @ ReEarlyBound ( _) , & ReEmpty ( _) )
500
+ | ( & ReEmpty ( _) , r @ ReFree ( _) )
501
+ | ( r @ ReFree ( _) , & ReEmpty ( _) )
502
+ | ( & ReEmpty ( _) , r @ ReScope ( _) )
503
+ | ( r @ ReScope ( _) , & ReEmpty ( _) ) => {
504
+ // all empty regions are less than early-bound, free,
505
+ // and scope regions
506
+ r
507
+ }
508
+
509
+ ( & ReEmpty ( a_ui) , & ReEmpty ( b_ui) ) => {
510
+ // empty regions are ordered according to the universe
511
+ // they are associated with
512
+ let ui = a_ui. min ( b_ui) ;
513
+ self . tcx ( ) . mk_region ( ReEmpty ( ui) )
514
+ }
515
+
516
+ ( & ReEmpty ( empty_ui) , & RePlaceholder ( placeholder) )
517
+ | ( & RePlaceholder ( placeholder) , & ReEmpty ( empty_ui) ) => {
518
+ // If this empty region is from a universe that can
519
+ // name the placeholder, then the placeholder is
520
+ // larger; otherwise, the only ancestor is `'static`.
521
+ if empty_ui. can_name ( placeholder. universe ) {
522
+ self . tcx ( ) . mk_region ( RePlaceholder ( placeholder) )
523
+ } else {
524
+ self . tcx ( ) . lifetimes . re_static
525
+ }
526
+ }
527
+
478
528
( & ReEarlyBound ( _) , & ReScope ( s_id) )
479
529
| ( & ReScope ( s_id) , & ReEarlyBound ( _) )
480
530
| ( & ReFree ( _) , & ReScope ( s_id) )
@@ -800,6 +850,26 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
800
850
}
801
851
}
802
852
853
+ // If we have a scenario like `exists<'a> { forall<'b> { 'b:
854
+ // 'a } }`, we wind up without any lower-bound -- all we have
855
+ // are placeholders as upper bounds, but the universe of the
856
+ // variable `'a` doesn't permit those placeholders.
857
+ for upper_bound in & upper_bounds {
858
+ if let ty:: RePlaceholder ( p) = upper_bound. region {
859
+ if node_universe. cannot_name ( p. universe ) {
860
+ let origin = self . var_infos [ node_idx] . origin . clone ( ) ;
861
+ errors. push ( RegionResolutionError :: UpperBoundUniverseConflict (
862
+ node_idx,
863
+ origin,
864
+ node_universe,
865
+ upper_bound. origin . clone ( ) ,
866
+ upper_bound. region ,
867
+ ) ) ;
868
+ return ;
869
+ }
870
+ }
871
+ }
872
+
803
873
// Errors in earlier passes can yield error variables without
804
874
// resolution errors here; delay ICE in favor of those errors.
805
875
self . tcx ( ) . sess . delay_span_bug (
@@ -914,7 +984,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
914
984
}
915
985
916
986
VerifyBound :: IsEmpty => {
917
- if let ty:: ReEmpty = min {
987
+ if let ty:: ReEmpty ( _ ) = min {
918
988
true
919
989
} else {
920
990
false
0 commit comments