@@ -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
@@ -196,7 +212,7 @@ impl RegionTracker {
196
212
///
197
213
/// Returns *a* culprit (there may be more than one).
198
214
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 {
200
216
return None ;
201
217
} ;
202
218
@@ -207,8 +223,7 @@ impl RegionTracker {
207
223
return None ;
208
224
} ;
209
225
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)
212
227
}
213
228
214
229
/// Determine if this SCC reaches a placeholder that isn't `placeholder_rvid`,
@@ -238,6 +253,9 @@ impl scc::Annotation for RegionTracker {
238
253
239
254
Self {
240
255
representative : self . representative . min ( other. representative ) ,
256
+ scc_placeholder_largest_universe : self
257
+ . scc_placeholder_largest_universe
258
+ . max ( other. scc_placeholder_largest_universe ) ,
241
259
..self . merge_reached ( other)
242
260
}
243
261
}
@@ -254,6 +272,7 @@ impl scc::Annotation for RegionTracker {
254
272
. min ( other. min_max_nameable_universe ) ,
255
273
reachable_placeholders : self . reachable_placeholders . merge ( other. reachable_placeholders ) ,
256
274
representative : self . representative ,
275
+ scc_placeholder_largest_universe : self . scc_placeholder_largest_universe ,
257
276
}
258
277
}
259
278
}
0 commit comments