@@ -72,7 +72,7 @@ pub struct RegionInferenceContext<'tcx> {
7272 /// The SCC computed from `constraints` and the constraint
7373 /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
7474 /// compute the values of each region.
75- pub constraint_sccs : Rc < ConstraintSccs > ,
75+ constraint_sccs : Rc < ConstraintSccs > ,
7676
7777 /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if
7878 /// `B: A`. This is used to compute the universal regions that are required
@@ -397,6 +397,39 @@ impl<'tcx> RegionInferenceContext<'tcx> {
397397 /// and (b) any universally quantified regions that it outlives,
398398 /// which in this case is just itself. R1 (`'b`) in contrast also
399399 /// 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`.
400433 fn init_free_and_bound_regions ( & mut self ) {
401434 // Update the names (if any)
402435 // This iterator has unstable order but we collect it all into an IndexVec
@@ -1412,6 +1445,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14121445 }
14131446 }
14141447
1448+ /// The minimum universe of any variable reachable from this
1449+ /// SCC, inside or outside of it.
14151450 fn scc_universe ( & self , scc : ConstraintSccIndex ) -> UniverseIndex {
14161451 self . constraint_sccs ( ) . annotation ( scc) . universe ( )
14171452 }
@@ -2151,6 +2186,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
21512186
21522187 /// Returns the representative `RegionVid` for a given SCC.
21532188 /// 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).
21542195 fn scc_representative ( & self , scc : ConstraintSccIndex ) -> RegionVid {
21552196 self . constraint_sccs . annotation ( scc) . representative
21562197 }
0 commit comments