@@ -126,7 +126,13 @@ pub(crate) struct RegionTracker {
126
126
/// regions reachable from this SCC.
127
127
min_max_nameable_universe : UniverseIndex ,
128
128
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.
130
136
min_universe_existential : Option < ( UniverseIndex , RegionVid ) > ,
131
137
132
138
/// The representative Region Variable Id for this SCC.
@@ -135,29 +141,39 @@ pub(crate) struct RegionTracker {
135
141
136
142
impl RegionTracker {
137
143
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,
142
162
min_placeholder : rvid,
143
163
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,
158
176
} ,
159
- min_max_nameable_universe : definition. universe ,
160
- representative : Representative :: new ( rvid, definition) ,
161
177
}
162
178
}
163
179
@@ -200,7 +216,7 @@ impl RegionTracker {
200
216
///
201
217
/// Returns *a* culprit (there may be more than one).
202
218
fn reaches_existential_that_cannot_name_us ( & self ) -> Option < RegionVid > {
203
- let Representative :: Placeholder ( _p ) = self . representative else {
219
+ let Some ( required_universe ) = self . scc_placeholder_largest_universe else {
204
220
return None ;
205
221
} ;
206
222
@@ -211,8 +227,7 @@ impl RegionTracker {
211
227
return None ;
212
228
} ;
213
229
214
- ( !self . reachable_placeholders . can_be_named_by ( reachable_lowest_max_u) )
215
- . then_some ( reachable_lowest_max_u_rvid)
230
+ ( !reachable_lowest_max_u. can_name ( required_universe) ) . then_some ( reachable_lowest_max_u_rvid)
216
231
}
217
232
218
233
/// Determine if this SCC reaches a placeholder that isn't `placeholder_rvid`,
@@ -242,6 +257,9 @@ impl scc::Annotation for RegionTracker {
242
257
243
258
Self {
244
259
representative : self . representative . min ( other. representative ) ,
260
+ scc_placeholder_largest_universe : self
261
+ . scc_placeholder_largest_universe
262
+ . max ( other. scc_placeholder_largest_universe ) ,
245
263
..self . merge_reached ( other)
246
264
}
247
265
}
@@ -258,6 +276,7 @@ impl scc::Annotation for RegionTracker {
258
276
. min ( other. min_max_nameable_universe ) ,
259
277
reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
260
278
representative : self . representative ,
279
+ scc_placeholder_largest_universe : self . scc_placeholder_largest_universe ,
261
280
}
262
281
}
263
282
}
0 commit comments