@@ -49,7 +49,10 @@ pub fn resolve<'tcx>(
4949 let mut values = resolver. infer_variable_values ( & mut errors) ;
5050 let re_erased = region_rels. tcx . lifetimes . re_erased ;
5151
52- values. values . iter_mut ( ) . for_each ( |v| * v = VarValue :: Value ( re_erased) ) ;
52+ values. values . iter_mut ( ) . for_each ( |v| match * v {
53+ VarValue :: Value ( ref mut r) => * r = re_erased,
54+ VarValue :: ErrorValue => { }
55+ } ) ;
5356 ( values, errors)
5457 }
5558 RegionckMode :: Erase { suppress_errors : true } => {
@@ -290,8 +293,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
290293
291294 // Find all the "upper bounds" -- that is, each region `b` such that
292295 // `r0 <= b` must hold.
293- let ( member_upper_bounds, _ ) =
294- self . collect_concrete_regions ( graph, member_vid, OUTGOING , None ) ;
296+ let ( member_upper_bounds, .. ) =
297+ self . collect_bounding_regions ( graph, member_vid, OUTGOING , None ) ;
295298
296299 // Get an iterator over the *available choice* -- that is,
297300 // each choice region `c` where `lb <= c` and `c <= ub` for all the
@@ -716,7 +719,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
716719 graph : & RegionGraph < ' tcx > ,
717720 errors : & mut Vec < RegionResolutionError < ' tcx > > ,
718721 ) {
719- debug ! ( "collect_var_errors" ) ;
722+ debug ! ( "collect_var_errors, var_data = {:#?}" , var_data . values ) ;
720723
721724 // This is the best way that I have found to suppress
722725 // duplicate and related errors. Basically we keep a set of
@@ -815,10 +818,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
815818 ) {
816819 // Errors in expanding nodes result from a lower-bound that is
817820 // not contained by an upper-bound.
818- let ( mut lower_bounds, lower_dup) =
819- self . collect_concrete_regions ( graph, node_idx, INCOMING , Some ( dup_vec) ) ;
820- let ( mut upper_bounds, upper_dup) =
821- self . collect_concrete_regions ( graph, node_idx, OUTGOING , Some ( dup_vec) ) ;
821+ let ( mut lower_bounds, lower_vid_bounds , lower_dup) =
822+ self . collect_bounding_regions ( graph, node_idx, INCOMING , Some ( dup_vec) ) ;
823+ let ( mut upper_bounds, _ , upper_dup) =
824+ self . collect_bounding_regions ( graph, node_idx, OUTGOING , Some ( dup_vec) ) ;
822825
823826 if lower_dup || upper_dup {
824827 return ;
@@ -874,15 +877,22 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
874877 // If we have a scenario like `exists<'a> { forall<'b> { 'b:
875878 // 'a } }`, we wind up without any lower-bound -- all we have
876879 // are placeholders as upper bounds, but the universe of the
877- // variable `'a` doesn't permit those placeholders.
880+ // variable `'a`, or some variable that `'a` has to outlive, doesn't
881+ // permit those placeholders.
882+ let min_universe = lower_vid_bounds
883+ . into_iter ( )
884+ . map ( |vid| self . var_infos [ vid] . universe )
885+ . min ( )
886+ . expect ( "lower_vid_bounds should at least include `node_idx`" ) ;
887+
878888 for upper_bound in & upper_bounds {
879889 if let ty:: RePlaceholder ( p) = upper_bound. region {
880- if node_universe . cannot_name ( p. universe ) {
890+ if min_universe . cannot_name ( p. universe ) {
881891 let origin = self . var_infos [ node_idx] . origin ;
882892 errors. push ( RegionResolutionError :: UpperBoundUniverseConflict (
883893 node_idx,
884894 origin,
885- node_universe ,
895+ min_universe ,
886896 upper_bound. origin . clone ( ) ,
887897 upper_bound. region ,
888898 ) ) ;
@@ -904,13 +914,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
904914 ) ;
905915 }
906916
907- fn collect_concrete_regions (
917+ fn collect_bounding_regions (
908918 & self ,
909919 graph : & RegionGraph < ' tcx > ,
910920 orig_node_idx : RegionVid ,
911921 dir : Direction ,
912922 mut dup_vec : Option < & mut IndexVec < RegionVid , Option < RegionVid > > > ,
913- ) -> ( Vec < RegionAndOrigin < ' tcx > > , bool ) {
923+ ) -> ( Vec < RegionAndOrigin < ' tcx > > , FxHashSet < RegionVid > , bool ) {
914924 struct WalkState < ' tcx > {
915925 set : FxHashSet < RegionVid > ,
916926 stack : Vec < RegionVid > ,
@@ -929,9 +939,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
929939 // direction specified
930940 process_edges ( & self . data , & mut state, graph, orig_node_idx, dir) ;
931941
932- while !state. stack . is_empty ( ) {
933- let node_idx = state. stack . pop ( ) . unwrap ( ) ;
934-
942+ while let Some ( node_idx) = state. stack . pop ( ) {
935943 // check whether we've visited this node on some previous walk
936944 if let Some ( dup_vec) = & mut dup_vec {
937945 if dup_vec[ node_idx] . is_none ( ) {
@@ -949,8 +957,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
949957 process_edges ( & self . data , & mut state, graph, node_idx, dir) ;
950958 }
951959
952- let WalkState { result, dup_found, .. } = state;
953- return ( result, dup_found) ;
960+ let WalkState { result, dup_found, set , .. } = state;
961+ return ( result, set , dup_found) ;
954962
955963 fn process_edges < ' tcx > (
956964 this : & RegionConstraintData < ' tcx > ,
0 commit comments