@@ -72,7 +72,7 @@ pub struct RegionInferenceContext<'tcx> {
72
72
/// The SCC computed from `constraints` and the constraint
73
73
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
74
74
/// compute the values of each region.
75
- pub constraint_sccs : Rc < ConstraintSccs > ,
75
+ constraint_sccs : Rc < ConstraintSccs > ,
76
76
77
77
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
78
78
/// `B: A`. This is used to compute the universal regions that are required
@@ -397,6 +397,39 @@ impl<'tcx> RegionInferenceContext<'tcx> {
397
397
/// and (b) any universally quantified regions that it outlives,
398
398
/// which in this case is just itself. R1 (`'b`) in contrast also
399
399
/// outlives `'a` and hence contains R0 and R1.
400
+ ///
401
+ /// This bit of logic also handles invalid universe relations
402
+ /// for higher-kinded types.
403
+ ///
404
+ // We Walk each SCC `A` and `B` such that `A: B`
405
+ // and ensure that universe(A) can see universe(B).
406
+ //
407
+ // This serves to enforce the 'empty/placeholder' hierarchy
408
+ // (described in more detail on `RegionKind`):
409
+ //
410
+ // ```
411
+ // static -----+
412
+ // | |
413
+ // empty(U0) placeholder(U1)
414
+ // | /
415
+ // empty(U1)
416
+ // ```
417
+ //
418
+ // In particular, imagine we have variables R0 in U0 and R1
419
+ // created in U1, and constraints like this;
420
+ //
421
+ // ```
422
+ // R1: !1 // R1 outlives the placeholder in U1
423
+ // R1: R0 // R1 outlives R0
424
+ // ```
425
+ //
426
+ // Here, we wish for R1 to be `'static`, because it
427
+ // cannot outlive `placeholder(U1)` and `empty(U0)` any other way.
428
+ //
429
+ // Thanks to this loop, what happens is that the `R1: R0`
430
+ // constraint has lowered the universe of `R1` to `U0`, which in turn
431
+ // means that the `R1: !1` constraint here will cause
432
+ // `R1` to become `'static`.
400
433
fn init_free_and_bound_regions ( & mut self ) {
401
434
// Update the names (if any)
402
435
// This iterator has unstable order but we collect it all into an IndexVec
@@ -1412,6 +1445,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1412
1445
}
1413
1446
}
1414
1447
1448
+ /// The minimum universe of any variable reachable from this
1449
+ /// SCC, inside or outside of it.
1415
1450
fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
1416
1451
self . constraint_sccs ( ) . annotation ( scc) . universe ( )
1417
1452
}
@@ -2151,6 +2186,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2151
2186
2152
2187
/// Returns the representative `RegionVid` for a given SCC.
2153
2188
/// See `RegionTracker` for how a region variable ID is chosen.
2189
+ ///
2190
+ /// It is a hacky way to manage checking regions for equality,
2191
+ /// since we can 'canonicalize' each region to the representative
2192
+ /// of its SCC and be sure that -- if they have the same repr --
2193
+ /// they *must* be equal (though not having the same repr does not
2194
+ /// mean they are unequal).
2154
2195
fn scc_representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
2155
2196
self . constraint_sccs . annotation ( scc) . representative
2156
2197
}
0 commit comments