@@ -29,7 +29,6 @@ use tracing::{debug, instrument, trace};
2929
3030use super :: { OutlivesSuggestionBuilder , RegionName , RegionNameSource } ;
3131use crate :: nll:: ConstraintDescription ;
32- use crate :: region_infer:: values:: RegionElement ;
3332use crate :: region_infer:: { BlameConstraint , TypeTest } ;
3433use crate :: session_diagnostics:: {
3534 FnMutError , FnMutReturnTypeErr , GenericDoesNotLiveLongEnough , LifetimeOutliveErr ,
@@ -104,38 +103,9 @@ pub(crate) enum RegionErrorKind<'tcx> {
104103 /// A generic bound failure for a type test (`T: 'a`).
105104 TypeTestError { type_test : TypeTest < ' tcx > } ,
106105
107- /// 'a outlives 'b, and both are placeholders.
108- PlaceholderOutlivesPlaceholder {
109- rvid_a : RegionVid ,
110- rvid_b : RegionVid ,
111- origin_a : ty:: PlaceholderRegion < ' tcx > ,
112- origin_b : ty:: PlaceholderRegion < ' tcx > ,
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 < ' tcx > ,
127- } ,
128-
129- /// Higher-ranked subtyping error. A placeholder outlives
130- /// either a location or a universal region.
131- PlaceholderOutlivesLocationOrUniversal {
132- /// The placeholder free region.
133- longer_fr : RegionVid ,
134- /// The region element that erroneously must be outlived by `longer_fr`.
135- error_element : RegionElement < ' tcx > ,
136- /// The placeholder region.
137- placeholder : ty:: PlaceholderRegion < ' tcx > ,
138- } ,
106+ /// 'p outlives 'r, which does not hold. 'p is always a placeholder
107+ /// and 'r is some other region.
108+ PlaceholderOutlivesIllegalRegion { longer_fr : RegionVid , illegally_outlived_r : RegionVid } ,
139109
140110 /// Any other lifetime error.
141111 RegionError {
@@ -228,60 +198,47 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
228198 let tcx = self . infcx . tcx ;
229199
230200 // find generic associated types in the given region 'lower_bound'
231- let gat_id_and_generics = self
201+ let scc = self . regioncx . constraint_sccs ( ) . scc ( lower_bound) ;
202+ let Some ( gat_hir_id) = self
232203 . regioncx
233- . placeholders_contained_in ( lower_bound)
234- . map ( |placeholder| {
235- if let Some ( id) = placeholder. bound . kind . get_id ( )
236- && let Some ( placeholder_id) = id. as_local ( )
237- && let gat_hir_id = tcx. local_def_id_to_hir_id ( placeholder_id)
238- && let Some ( generics_impl) =
239- tcx. parent_hir_node ( tcx. parent_hir_id ( gat_hir_id) ) . generics ( )
240- {
241- Some ( ( gat_hir_id, generics_impl) )
242- } else {
243- None
244- }
245- } )
246- . collect :: < Vec < _ > > ( ) ;
247- debug ! ( ?gat_id_and_generics) ;
204+ . placeholder_representative ( scc)
205+ . and_then ( |placeholder| placeholder. bound . kind . get_id ( ) )
206+ . and_then ( |id| id. as_local ( ) )
207+ . map ( |local| self . infcx . tcx . local_def_id_to_hir_id ( local) )
208+ else {
209+ return ;
210+ } ;
248211
249212 // Look for the where-bound which introduces the placeholder.
250213 // As we're using the HIR, we need to handle both `for<'a> T: Trait<'a>`
251214 // and `T: for<'a> Trait`<'a>.
252215 let mut hrtb_bounds = vec ! [ ] ;
253- gat_id_and_generics. iter ( ) . flatten ( ) . for_each ( |& ( gat_hir_id, generics) | {
254- for pred in generics. predicates {
255- let BoundPredicate ( WhereBoundPredicate { bound_generic_params, bounds, .. } ) =
256- pred. kind
257- else {
258- continue ;
259- } ;
260- if bound_generic_params
261- . iter ( )
262- . rfind ( |bgp| tcx. local_def_id_to_hir_id ( bgp. def_id ) == gat_hir_id)
263- . is_some ( )
264- {
265- for bound in * bounds {
266- hrtb_bounds. push ( bound) ;
267- }
268- } else {
269- for bound in * bounds {
270- if let Trait ( trait_bound) = bound {
271- if trait_bound
272- . bound_generic_params
273- . iter ( )
274- . rfind ( |bgp| tcx. local_def_id_to_hir_id ( bgp. def_id ) == gat_hir_id)
275- . is_some ( )
276- {
277- hrtb_bounds. push ( bound) ;
278- return ;
279- }
280- }
281- }
216+
217+ // FIXME(amandasystems) we can probably flatten this.
218+ for pred in self
219+ . infcx
220+ . tcx
221+ . parent_hir_node ( self . infcx . tcx . parent_hir_id ( gat_hir_id) )
222+ . generics ( )
223+ . map ( |gen_impl| gen_impl. predicates )
224+ . into_iter ( )
225+ . flatten ( )
226+ {
227+ let BoundPredicate ( WhereBoundPredicate { bound_generic_params, bounds, .. } ) =
228+ pred. kind
229+ else {
230+ continue ;
231+ } ;
232+ if bound_generic_params
233+ . iter ( )
234+ . rfind ( |bgp| self . infcx . tcx . local_def_id_to_hir_id ( bgp. def_id ) == gat_hir_id)
235+ . is_some ( )
236+ {
237+ for bound in * bounds {
238+ hrtb_bounds. push ( bound) ;
282239 }
283240 }
284- } ) ;
241+ }
285242 debug ! ( ?hrtb_bounds) ;
286243
287244 let mut suggestions = vec ! [ ] ;
@@ -384,56 +341,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
384341 }
385342 }
386343
387- RegionErrorKind :: PlaceholderOutlivesLocationOrUniversal {
344+ RegionErrorKind :: PlaceholderOutlivesIllegalRegion {
388345 longer_fr,
389- placeholder,
390- error_element,
391- } => self . report_erroneous_rvid_reaches_placeholder (
392- longer_fr,
393- placeholder,
394- self . regioncx . region_from_element ( longer_fr, & error_element) ,
395- ) ,
396- RegionErrorKind :: PlaceholderOutlivesPlaceholder {
397- rvid_a,
398- rvid_b,
399- origin_a,
400- origin_b,
346+ illegally_outlived_r,
401347 } => {
402- debug ! (
403- "Placeholder mismatch: {rvid_a:?} ({origin_a:?}) reaches {rvid_b:?} ({origin_b:?})"
404- ) ;
405-
406- let cause = self
407- . regioncx
408- . best_blame_constraint (
409- rvid_a,
410- NllRegionVariableOrigin :: Placeholder ( origin_a) ,
411- rvid_b,
412- )
413- . 0
414- . cause ;
415-
416- // FIXME We may be able to shorten the code path here, and immediately
417- // report a `RegionResolutionError::UpperBoundUniverseConflict`, but
418- // that's left for a future refactoring.
419- self . regioncx . universe_info ( origin_a. universe ) . report_erroneous_element (
420- self ,
421- origin_a,
422- Some ( origin_b) ,
423- cause,
424- ) ;
348+ self . report_erroneous_rvid_reaches_placeholder ( longer_fr, illegally_outlived_r)
425349 }
426350
427- RegionErrorKind :: PlaceholderOutlivesExistentialThatCannotNameIt {
428- longer_fr,
429- existential_that_cannot_name_longer,
430- placeholder,
431- } => self . report_erroneous_rvid_reaches_placeholder (
432- longer_fr,
433- placeholder,
434- existential_that_cannot_name_longer,
435- ) ,
436-
437351 RegionErrorKind :: RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {
438352 if is_reported {
439353 self . report_region_error (
0 commit comments