@@ -82,6 +82,16 @@ pub enum RegionResolutionError<'tcx> {
8282 Region < ' tcx > ,
8383 ) ,
8484
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+
8595 /// Indicates a failure of a `MemberConstraint`. These arise during
8696 /// impl trait processing explicitly -- basically, the impl trait's hidden type
8797 /// included some region that it was not supposed to.
@@ -149,7 +159,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
149159 fn construct_var_data ( & self , tcx : TyCtxt < ' tcx > ) -> LexicalRegionResolutions < ' tcx > {
150160 LexicalRegionResolutions {
151161 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+ ) ,
153170 }
154171 }
155172
@@ -381,8 +398,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
381398 // This is a specialized version of the `lub_concrete_regions`
382399 // check below for a common case, here purely as an
383400 // 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+ }
386406 }
387407
388408 let mut lub = self . lub_concrete_regions ( a_region, cur_region) ;
@@ -399,7 +419,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
399419 // tighter bound than `'static`.
400420 //
401421 // (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.)
402- let b_universe = self . var_infos [ b_vid] . universe ;
403422 if let ty:: RePlaceholder ( p) = lub {
404423 if b_universe. cannot_name ( p. universe ) {
405424 lub = self . tcx ( ) . lifetimes . re_static ;
@@ -445,7 +464,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
445464 self . lub_concrete_regions ( a, b) == b
446465 }
447466
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").
449472 fn lub_concrete_regions ( & self , a : Region < ' tcx > , b : Region < ' tcx > ) -> Region < ' tcx > {
450473 let r = match ( a, b) {
451474 ( & ty:: ReClosureBound ( ..) , _)
@@ -457,14 +480,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
457480 bug ! ( "cannot relate region: LUB({:?}, {:?})" , a, b) ;
458481 }
459482
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-
468483 ( & ReVar ( v_id) , _) | ( _, & ReVar ( v_id) ) => {
469484 span_bug ! (
470485 self . var_infos[ v_id] . origin. span( ) ,
@@ -475,6 +490,41 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
475490 ) ;
476491 }
477492
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+
478528 ( & ReEarlyBound ( _) , & ReScope ( s_id) )
479529 | ( & ReScope ( s_id) , & ReEarlyBound ( _) )
480530 | ( & ReFree ( _) , & ReScope ( s_id) )
@@ -800,6 +850,26 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
800850 }
801851 }
802852
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+
803873 // Errors in earlier passes can yield error variables without
804874 // resolution errors here; delay ICE in favor of those errors.
805875 self . tcx ( ) . sess . delay_span_bug (
@@ -914,7 +984,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
914984 }
915985
916986 VerifyBound :: IsEmpty => {
917- if let ty:: ReEmpty = min {
987+ if let ty:: ReEmpty ( _ ) = min {
918988 true
919989 } else {
920990 false
0 commit comments