@@ -104,14 +104,18 @@ pub(crate) enum RegionErrorKind<'tcx> {
104104 /// A generic bound failure for a type test (`T: 'a`).
105105 TypeTestError { type_test : TypeTest < ' tcx > } ,
106106
107- /// Higher-ranked subtyping error.
108- BoundUniversalRegionError {
107+ /// 'a outlives 'b, which does not hold. 'a is always a
108+ /// placeholder and 'b is either an existential that cannot name
109+ /// 'a, or another placeholder.
110+ PlaceholderOutlivesIllegalRegion { longer_fr : RegionVid , illegally_outlived_r : RegionVid } ,
111+
112+ /// Higher-ranked subtyping error. A placeholder outlives
113+ /// either a location or a universal region.
114+ PlaceholderOutlivesLocationOrUniversal {
109115 /// The placeholder free region.
110116 longer_fr : RegionVid ,
111117 /// The region element that erroneously must be outlived by `longer_fr`.
112118 error_element : RegionElement ,
113- /// The placeholder region.
114- placeholder : ty:: PlaceholderRegion ,
115119 } ,
116120
117121 /// Any other lifetime error.
@@ -201,64 +205,38 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
201205 & self ,
202206 diag : & mut Diag < ' _ > ,
203207 lower_bound : RegionVid ,
204- ) {
208+ ) -> Option < ( ) > {
205209 let tcx = self . infcx . tcx ;
206210
207211 // 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) ;
212+ let scc = self . regioncx . constraint_sccs ( ) . scc ( lower_bound) ;
213+ let placeholder: ty:: PlaceholderRegion = self . regioncx . placeholder_representative ( scc) ?;
214+ let placeholder_id = placeholder. bound . kind . get_id ( ) ?. as_local ( ) ?;
215+ let gat_hir_id = self . infcx . tcx . local_def_id_to_hir_id ( placeholder_id) ;
216+ let generics_impl =
217+ self . infcx . tcx . parent_hir_node ( self . infcx . tcx . parent_hir_id ( gat_hir_id) ) . generics ( ) ?;
225218
226219 // Look for the where-bound which introduces the placeholder.
227220 // As we're using the HIR, we need to handle both `for<'a> T: Trait<'a>`
228221 // and `T: for<'a> Trait`<'a>.
229222 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- }
223+
224+ for pred in generics_impl. predicates {
225+ let BoundPredicate ( WhereBoundPredicate { bound_generic_params, bounds, .. } ) =
226+ pred. kind
227+ else {
228+ continue ;
229+ } ;
230+ if bound_generic_params
231+ . iter ( )
232+ . rfind ( |bgp| self . infcx . tcx . local_def_id_to_hir_id ( bgp. def_id ) == gat_hir_id)
233+ . is_some ( )
234+ {
235+ for bound in * bounds {
236+ hrtb_bounds. push ( bound) ;
259237 }
260238 }
261- } ) ;
239+ }
262240 debug ! ( ?hrtb_bounds) ;
263241
264242 let mut suggestions = vec ! [ ] ;
@@ -304,6 +282,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
304282 Applicability :: MaybeIncorrect ,
305283 ) ;
306284 }
285+ Some ( ( ) )
307286 }
308287
309288 /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`.
@@ -361,28 +340,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
361340 }
362341 }
363342
364- RegionErrorKind :: BoundUniversalRegionError {
343+ RegionErrorKind :: PlaceholderOutlivesLocationOrUniversal {
365344 longer_fr,
366- placeholder,
367345 error_element,
368- } => {
369- let error_vid = self . regioncx . region_from_element ( longer_fr, & error_element) ;
370-
371- // Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
372- let cause = self
373- . regioncx
374- . best_blame_constraint (
375- longer_fr,
376- NllRegionVariableOrigin :: Placeholder ( placeholder) ,
377- error_vid,
378- )
379- . 0
380- . cause ;
381-
382- let universe = placeholder. universe ;
383- let universe_info = self . regioncx . universe_info ( universe) ;
346+ } => self . report_erroneous_rvid_reaches_placeholder (
347+ longer_fr,
348+ self . regioncx . region_from_element ( longer_fr, & error_element) ,
349+ ) ,
384350
385- universe_info. report_erroneous_element ( self , placeholder, error_element, cause) ;
351+ RegionErrorKind :: PlaceholderOutlivesIllegalRegion {
352+ longer_fr,
353+ illegally_outlived_r,
354+ } => {
355+ self . report_erroneous_rvid_reaches_placeholder ( longer_fr, illegally_outlived_r)
386356 }
387357
388358 RegionErrorKind :: RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {
0 commit comments