@@ -104,8 +104,31 @@ pub(crate) enum RegionErrorKind<'tcx> {
104104    /// A generic bound failure for a type test (`T: 'a`). 
105105TypeTestError  {  type_test :  TypeTest < ' tcx >  } , 
106106
107-     /// Higher-ranked subtyping error. 
108- BoundUniversalRegionError  { 
107+     /// 'a outlives 'b, and both are placeholders. 
108+ PlaceholderOutlivesPlaceholder  { 
109+         rvid_a :  RegionVid , 
110+         rvid_b :  RegionVid , 
111+         origin_a :  ty:: PlaceholderRegion , 
112+         origin_b :  ty:: PlaceholderRegion , 
113+     } , 
114+ 
115+     /// Indicates that a placeholder has a universe too large for one 
116+ /// of its member existentials, or, equivalently, that there is 
117+ /// a path through the outlives constraint graph from a placeholder 
118+ /// to an existential region that cannot name it. 
119+ PlaceholderOutlivesExistentialThatCannotNameIt  { 
120+         /// the placeholder that transitively outlives an 
121+ /// existential that shouldn't leak into it 
122+ longer_fr :  RegionVid , 
123+         /// The existential leaking into `longer_fr`. 
124+ existential_that_cannot_name_longer :  RegionVid , 
125+         // `longer_fr`'s originating placeholder region. 
126+         placeholder :  ty:: PlaceholderRegion , 
127+     } , 
128+ 
129+     /// Higher-ranked subtyping error. A placeholder outlives 
130+ /// either a location or a universal region. 
131+ PlaceholderOutlivesLocationOrUniversal  { 
109132        /// The placeholder free region. 
110133longer_fr :  RegionVid , 
111134        /// The region element that erroneously must be outlived by `longer_fr`. 
@@ -201,64 +224,38 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
201224        & self , 
202225        diag :  & mut  Diag < ' _ > , 
203226        lower_bound :  RegionVid , 
204-     )  { 
227+     )  ->  Option < ( ) >   { 
205228        let  tcx = self . infcx . tcx ; 
206229
207230        // find generic associated types in the given region 'lower_bound' 
208-         let  gat_id_and_generics = self 
209-             . regioncx 
210-             . placeholders_contained_in ( lower_bound) 
211-             . map ( |placeholder| { 
212-                 if  let  Some ( id)  = placeholder. bound . kind . get_id ( ) 
213-                     && let  Some ( placeholder_id)  = id. as_local ( ) 
214-                     && let  gat_hir_id = tcx. local_def_id_to_hir_id ( placeholder_id) 
215-                     && let  Some ( generics_impl)  =
216-                         tcx. parent_hir_node ( tcx. parent_hir_id ( gat_hir_id) ) . generics ( ) 
217-                 { 
218-                     Some ( ( gat_hir_id,  generics_impl) ) 
219-                 }  else  { 
220-                     None 
221-                 } 
222-             } ) 
223-             . collect :: < Vec < _ > > ( ) ; 
224-         debug ! ( ?gat_id_and_generics) ; 
231+         let  scc = self . regioncx . constraint_sccs ( ) . scc ( lower_bound) ; 
232+         let  placeholder:  ty:: PlaceholderRegion  = self . regioncx . placeholder_representative ( scc) ?; 
233+         let  placeholder_id = placeholder. bound . kind . get_id ( ) ?. as_local ( ) ?; 
234+         let  gat_hir_id = self . infcx . tcx . local_def_id_to_hir_id ( placeholder_id) ; 
235+         let  generics_impl =
236+             self . infcx . tcx . parent_hir_node ( self . infcx . tcx . parent_hir_id ( gat_hir_id) ) . generics ( ) ?; 
225237
226238        // Look for the where-bound which introduces the placeholder. 
227239        // As we're using the HIR, we need to handle both `for<'a> T: Trait<'a>` 
228240        // and `T: for<'a> Trait`<'a>. 
229241        let  mut  hrtb_bounds = vec ! [ ] ; 
230-         gat_id_and_generics. iter ( ) . flatten ( ) . for_each ( |& ( gat_hir_id,  generics) | { 
231-             for  pred in  generics. predicates  { 
232-                 let  BoundPredicate ( WhereBoundPredicate  {  bound_generic_params,  bounds,  .. } )  =
233-                     pred. kind 
234-                 else  { 
235-                     continue ; 
236-                 } ; 
237-                 if  bound_generic_params
238-                     . iter ( ) 
239-                     . rfind ( |bgp| tcx. local_def_id_to_hir_id ( bgp. def_id )  == gat_hir_id) 
240-                     . is_some ( ) 
241-                 { 
242-                     for  bound in  * bounds { 
243-                         hrtb_bounds. push ( bound) ; 
244-                     } 
245-                 }  else  { 
246-                     for  bound in  * bounds { 
247-                         if  let  Trait ( trait_bound)  = bound { 
248-                             if  trait_bound
249-                                 . bound_generic_params 
250-                                 . iter ( ) 
251-                                 . rfind ( |bgp| tcx. local_def_id_to_hir_id ( bgp. def_id )  == gat_hir_id) 
252-                                 . is_some ( ) 
253-                             { 
254-                                 hrtb_bounds. push ( bound) ; 
255-                                 return ; 
256-                             } 
257-                         } 
258-                     } 
242+ 
243+         for  pred in  generics_impl. predicates  { 
244+             let  BoundPredicate ( WhereBoundPredicate  {  bound_generic_params,  bounds,  .. } )  =
245+                 pred. kind 
246+             else  { 
247+                 continue ; 
248+             } ; 
249+             if  bound_generic_params
250+                 . iter ( ) 
251+                 . rfind ( |bgp| self . infcx . tcx . local_def_id_to_hir_id ( bgp. def_id )  == gat_hir_id) 
252+                 . is_some ( ) 
253+             { 
254+                 for  bound in  * bounds { 
255+                     hrtb_bounds. push ( bound) ; 
259256                } 
260257            } 
261-         } ) ; 
258+         } 
262259        debug ! ( ?hrtb_bounds) ; 
263260
264261        let  mut  suggestions = vec ! [ ] ; 
@@ -304,6 +301,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
304301                Applicability :: MaybeIncorrect , 
305302            ) ; 
306303        } 
304+         Some ( ( ) ) 
307305    } 
308306
309307    /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`. 
@@ -361,30 +359,56 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
361359                    } 
362360                } 
363361
364-                 RegionErrorKind :: BoundUniversalRegionError  { 
362+                 RegionErrorKind :: PlaceholderOutlivesLocationOrUniversal  { 
365363                    longer_fr, 
366364                    placeholder, 
367365                    error_element, 
366+                 }  => self . report_erroneous_rvid_reaches_placeholder ( 
367+                     longer_fr, 
368+                     placeholder, 
369+                     self . regioncx . region_from_element ( longer_fr,  & error_element) , 
370+                 ) , 
371+                 RegionErrorKind :: PlaceholderOutlivesPlaceholder  { 
372+                     rvid_a, 
373+                     rvid_b, 
374+                     origin_a, 
375+                     origin_b, 
368376                }  => { 
369-                     let  error_vid = self . regioncx . region_from_element ( longer_fr,  & error_element) ; 
377+                     debug ! ( 
378+                         "Placeholder mismatch: {rvid_a:?} ({origin_a:?}) reaches {rvid_b:?} ({origin_b:?})" 
379+                     ) ; 
370380
371-                     // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. 
372381                    let  cause = self 
373382                        . regioncx 
374383                        . best_blame_constraint ( 
375-                             longer_fr , 
376-                             NllRegionVariableOrigin :: Placeholder ( placeholder ) , 
377-                             error_vid , 
384+                             rvid_a , 
385+                             NllRegionVariableOrigin :: Placeholder ( origin_a ) , 
386+                             rvid_b , 
378387                        ) 
379388                        . 0 
380389                        . cause ; 
381390
382-                     let  universe = placeholder. universe ; 
383-                     let  universe_info = self . regioncx . universe_info ( universe) ; 
384- 
385-                     universe_info. report_erroneous_element ( self ,  placeholder,  error_element,  cause) ; 
391+                     // FIXME We may be able to shorten the code path here, and immediately 
392+                     // report a `RegionResolutionError::UpperBoundUniverseConflict`, but 
393+                     // that's left for a future refactoring. 
394+                     self . regioncx . universe_info ( origin_a. universe ) . report_erroneous_element ( 
395+                         self , 
396+                         origin_a, 
397+                         Some ( origin_b) , 
398+                         cause, 
399+                     ) ; 
386400                } 
387401
402+                 RegionErrorKind :: PlaceholderOutlivesExistentialThatCannotNameIt  { 
403+                     longer_fr, 
404+                     existential_that_cannot_name_longer, 
405+                     placeholder, 
406+                 }  => self . report_erroneous_rvid_reaches_placeholder ( 
407+                     longer_fr, 
408+                     placeholder, 
409+                     existential_that_cannot_name_longer, 
410+                 ) , 
411+ 
388412                RegionErrorKind :: RegionError  {  fr_origin,  longer_fr,  shorter_fr,  is_reported }  => { 
389413                    if  is_reported { 
390414                        self . report_region_error ( 
0 commit comments