@@ -153,7 +153,7 @@ impl RegionTracker {
153
153
154
154
Self {
155
155
// The largest reachable universe from a rvid is its
156
- // declared largest reachable one.
156
+ // declared one.
157
157
min_max_universe_reached : ( definition. universe , rvid) ,
158
158
reachable_placeholders,
159
159
representative : Representative :: new ( rvid, definition) ,
@@ -175,17 +175,15 @@ impl RegionTracker {
175
175
|| other. reachable_placeholders . can_be_named_by ( self . max_nameable_universe ( ) )
176
176
}
177
177
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 ) > {
182
180
let PlaceholderReachability :: Placeholders { max_universe : ( max_u, max_u_rvid) , .. } =
183
181
self . reachable_placeholders
184
182
else {
185
183
return None ;
186
184
} ;
187
185
188
- if min_u . can_name ( max_u) {
186
+ if self . max_nameable_universe ( ) . can_name ( max_u) {
189
187
return None ;
190
188
}
191
189
@@ -216,7 +214,7 @@ impl scc::Annotation for RegionTracker {
216
214
}
217
215
218
216
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 ( ) ;
220
218
self . min_max_universe_reached = pick_min_max_universe ( self , other) ;
221
219
// This detail is subtle. We stop early here, because there may be multiple
222
220
// illegally reached regions, but they are not equally good as blame candidates.
@@ -227,8 +225,8 @@ impl scc::Annotation for RegionTracker {
227
225
// FIXME: a potential optimisation if this is slow is to reimplement
228
226
// this check as a boolean fuse, since it will idempotently turn
229
227
// 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!" ) ;
232
230
self
233
231
} else {
234
232
self . reachable_placeholders =
@@ -426,40 +424,48 @@ fn rewrite_placeholder_outlives<'tcx>(
426
424
427
425
let annotation = & annotations[ scc] ;
428
426
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 {
435
428
continue ;
436
429
} ;
437
430
438
- let min_u = annotation. max_nameable_universe ( ) ;
439
-
440
431
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 {:?}" ,
442
433
annotation. representative
443
434
) ;
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.
444
445
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.
448
448
let small_universed_rvid = find_region (
449
449
outlives_constraints,
450
450
constraint_graph. get_or_init ( || outlives_constraints. graph ( definitions. len ( ) ) ) ,
451
451
definitions,
452
452
max_u_rvid,
453
- |r : RegionVid | definitions[ r] . universe == min_u ,
453
+ |r : RegionVid | definitions[ r] . universe == annotation . max_nameable_universe ( ) ,
454
454
fr_static,
455
455
) ;
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
+ ) ;
457
460
small_universed_rvid
458
461
} 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 .
460
463
max_u_rvid
461
464
} ;
462
465
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
+
463
469
outlives_static. insert ( scc) ;
464
470
outlives_constraints. push ( OutlivesConstraint {
465
471
sup : annotation. representative . rvid ( ) ,
0 commit comments