@@ -126,7 +126,13 @@ pub(crate) struct RegionTracker {
126126 /// regions reachable from this SCC.
127127 min_max_nameable_universe : UniverseIndex ,
128128
129- /// The existential region with the smallest universe, if any.
129+ /// The largest universe of a placeholder in this SCC. Iff
130+ /// an existential can name this universe it's allowed to
131+ /// reach us.
132+ scc_placeholder_largest_universe : Option < UniverseIndex > ,
133+
134+ /// The reached existential region with the smallest universe, if any. This
135+ /// is an upper bound on the universe.
130136 min_universe_existential : Option < ( UniverseIndex , RegionVid ) > ,
131137
132138 /// The representative Region Variable Id for this SCC.
@@ -135,29 +141,39 @@ pub(crate) struct RegionTracker {
135141
136142impl RegionTracker {
137143 pub ( crate ) fn new ( rvid : RegionVid , definition : & RegionDefinition < ' _ > ) -> Self {
138- let reachable_placeholders =
139- if matches ! ( definition. origin, NllRegionVariableOrigin :: Placeholder ( _) ) {
140- PlaceholderReachability :: Placeholders {
141- max_universe : ( definition. universe , rvid) ,
144+ use NllRegionVariableOrigin :: * ;
145+ use PlaceholderReachability :: * ;
146+
147+ let min_max_nameable_universe = definition. universe ;
148+ let representative = Representative :: new ( rvid, definition) ;
149+ let universe_and_rvid = ( definition. universe , rvid) ;
150+
151+ match definition. origin {
152+ FreeRegion => Self {
153+ reachable_placeholders : NoPlaceholders ,
154+ min_max_nameable_universe,
155+ scc_placeholder_largest_universe : None ,
156+ min_universe_existential : None ,
157+ representative,
158+ } ,
159+ Placeholder ( _) => Self {
160+ reachable_placeholders : Placeholders {
161+ max_universe : universe_and_rvid,
142162 min_placeholder : rvid,
143163 max_placeholder : rvid,
144- }
145- } else {
146- PlaceholderReachability :: NoPlaceholders
147- } ;
148-
149- Self {
150- reachable_placeholders,
151- min_universe_existential : if matches ! (
152- definition. origin,
153- NllRegionVariableOrigin :: Existential { .. }
154- ) {
155- Some ( ( definition. universe , rvid) )
156- } else {
157- None
164+ } ,
165+ min_max_nameable_universe,
166+ scc_placeholder_largest_universe : Some ( definition. universe ) ,
167+ min_universe_existential : None ,
168+ representative,
169+ } ,
170+ Existential { .. } => Self {
171+ reachable_placeholders : NoPlaceholders ,
172+ min_max_nameable_universe,
173+ scc_placeholder_largest_universe : None ,
174+ min_universe_existential : Some ( universe_and_rvid) ,
175+ representative,
158176 } ,
159- min_max_nameable_universe : definition. universe ,
160- representative : Representative :: new ( rvid, definition) ,
161177 }
162178 }
163179
@@ -196,7 +212,7 @@ impl RegionTracker {
196212 ///
197213 /// Returns *a* culprit (there may be more than one).
198214 fn reaches_existential_that_cannot_name_us ( & self ) -> Option < RegionVid > {
199- let Representative :: Placeholder ( _p ) = self . representative else {
215+ let Some ( required_universe ) = self . scc_placeholder_largest_universe else {
200216 return None ;
201217 } ;
202218
@@ -207,8 +223,7 @@ impl RegionTracker {
207223 return None ;
208224 } ;
209225
210- ( !self . reachable_placeholders . can_be_named_by ( reachable_lowest_max_u) )
211- . then_some ( reachable_lowest_max_u_rvid)
226+ ( !reachable_lowest_max_u. can_name ( required_universe) ) . then_some ( reachable_lowest_max_u_rvid)
212227 }
213228
214229 /// Determine if this SCC reaches a placeholder that isn't `placeholder_rvid`,
@@ -238,6 +253,9 @@ impl scc::Annotation for RegionTracker {
238253
239254 Self {
240255 representative : self . representative . min ( other. representative ) ,
256+ scc_placeholder_largest_universe : self
257+ . scc_placeholder_largest_universe
258+ . max ( other. scc_placeholder_largest_universe ) ,
241259 ..self . merge_reached ( other)
242260 }
243261 }
@@ -254,6 +272,7 @@ impl scc::Annotation for RegionTracker {
254272 . min ( other. min_max_nameable_universe ) ,
255273 reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
256274 representative : self . representative ,
275+ scc_placeholder_largest_universe : self . scc_placeholder_largest_universe ,
257276 }
258277 }
259278}
0 commit comments