@@ -153,7 +153,7 @@ impl RegionTracker {
153153
154154 Self {
155155 // The largest reachable universe from a rvid is its
156- // declared largest reachable one.
156+ // declared one.
157157 min_max_universe_reached : ( definition. universe , rvid) ,
158158 reachable_placeholders,
159159 representative : Representative :: new ( rvid, definition) ,
@@ -175,17 +175,15 @@ impl RegionTracker {
175175 || other. reachable_placeholders . can_be_named_by ( self . max_nameable_universe ( ) )
176176 }
177177
178- /// If this SCC reaches an universe that's too large, return it.
179- fn reaches_too_large_universe ( & self ) -> Option < ( RegionVid , UniverseIndex ) > {
180- let min_u = self . max_nameable_universe ( ) ;
181-
178+ /// If this SCC reaches a placeholder it can't name, return it.
179+ fn unnameable_placeholder ( & self ) -> Option < ( RegionVid , UniverseIndex ) > {
182180 let PlaceholderReachability :: Placeholders { max_universe : ( max_u, max_u_rvid) , .. } =
183181 self . reachable_placeholders
184182 else {
185183 return None ;
186184 } ;
187185
188- if min_u . can_name ( max_u) {
186+ if self . max_nameable_universe ( ) . can_name ( max_u) {
189187 return None ;
190188 }
191189
@@ -216,7 +214,7 @@ impl scc::Annotation for RegionTracker {
216214 }
217215
218216 fn merge_reached ( mut self , other : Self ) -> Self {
219- let already_has_placeholder_violation = self . reaches_too_large_universe ( ) . is_some ( ) ;
217+ let already_has_unnameable_placeholder = self . unnameable_placeholder ( ) . is_some ( ) ;
220218 self . min_max_universe_reached = pick_min_max_universe ( self , other) ;
221219 // This detail is subtle. We stop early here, because there may be multiple
222220 // illegally reached regions, but they are not equally good as blame candidates.
@@ -227,8 +225,8 @@ impl scc::Annotation for RegionTracker {
227225 // FIXME: a potential optimisation if this is slow is to reimplement
228226 // this check as a boolean fuse, since it will idempotently turn
229227 // true once triggered and never go false again.
230- if already_has_placeholder_violation {
231- debug ! ( "SCC already has a placeholder violation ; no use looking for more!" ) ;
228+ if already_has_unnameable_placeholder {
229+ debug ! ( "SCC already has an unnameable placeholder ; no use looking for more!" ) ;
232230 self
233231 } else {
234232 self . reachable_placeholders =
@@ -426,40 +424,48 @@ fn rewrite_placeholder_outlives<'tcx>(
426424
427425 let annotation = & annotations[ scc] ;
428426
429- // Figure out if there is a universe violation in this SCC.
430- // This can happen in two cases: either one of our placeholders
431- // had its universe lowered from reaching a region with a lower universe,
432- // (in which case we blame the lower universe's region), or because we reached
433- // a larger universe (in which case we blame the larger universe's region).
434- let Some ( ( max_u_rvid, max_u) ) = annotation. reaches_too_large_universe ( ) else {
427+ let Some ( ( max_u_rvid, max_u) ) = annotation. unnameable_placeholder ( ) else {
435428 continue ;
436429 } ;
437430
438- let min_u = annotation. max_nameable_universe ( ) ;
439-
440431 debug ! (
441- "Universe {max_u:?} is too large for its SCC, represented by {:?}" ,
432+ "Placeholder universe {max_u:?} is too large for its SCC, represented by {:?}" ,
442433 annotation. representative
443434 ) ;
435+
436+ // We only add one `r: 'static` constraint per SCC, where `r` is the SCC representative.
437+ // That constraint is annotated with some outlives relation `tries: unnameable` where
438+ // `unnameable` is unnameable from `tries` and there is a path in the constraint
439+ // graph between them.
440+ //
441+ // We prefer the representative as `tries` in all cases but one: where the problem
442+ // is that the SCC has had its universe lowered to accomodate some other region and
443+ // no longer can name its representative. In that case, we blame `r: low_u`, where `low_u`
444+ // cannot name `r` so that any explanation always starts with the SCC representative.
444445 let blame_to = if annotation. representative . rvid ( ) == max_u_rvid {
445- // We originally had a large enough universe to fit all our reachable
446- // placeholders, but had it lowered because we also reached something
447- // small-universed. In this case, that's to blame!
446+ // The SCC's representative is not nameable from some region
447+ // that ends up in the SCC.
448448 let small_universed_rvid = find_region (
449449 outlives_constraints,
450450 constraint_graph. get_or_init ( || outlives_constraints. graph ( definitions. len ( ) ) ) ,
451451 definitions,
452452 max_u_rvid,
453- |r : RegionVid | definitions[ r] . universe == min_u ,
453+ |r : RegionVid | definitions[ r] . universe == annotation . max_nameable_universe ( ) ,
454454 fr_static,
455455 ) ;
456- debug ! ( "{small_universed_rvid:?} lowered our universe to {min_u:?}" ) ;
456+ debug ! (
457+ "{small_universed_rvid:?} lowered our universe to {:?}" ,
458+ annotation. max_nameable_universe( )
459+ ) ;
457460 small_universed_rvid
458461 } else {
459- // The problem is that we, who have a small universe, reach a large one .
462+ // `max_u_rvid` is not nameable by the SCC's representative .
460463 max_u_rvid
461464 } ;
462465
466+ // FIXME: if we can extract a useful blame span here, future error
467+ // reporting and constraint search can be simplified. That does however
468+
463469 outlives_static. insert ( scc) ;
464470 outlives_constraints. push ( OutlivesConstraint {
465471 sup : annotation. representative . rvid ( ) ,
0 commit comments