Skip to content

Commit 23899d8

Browse files
committed
Be more restrictive of when we add placeholder-existential errors
1 parent 12aa8f9 commit 23899d8

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

compiler/rustc_borrowck/src/handle_placeholders.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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

136142
impl 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

@@ -200,7 +216,7 @@ impl RegionTracker {
200216
///
201217
/// Returns *a* culprit (there may be more than one).
202218
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 {
204220
return None;
205221
};
206222

@@ -211,8 +227,7 @@ impl RegionTracker {
211227
return None;
212228
};
213229

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)
216231
}
217232

218233
/// Determine if this SCC reaches a placeholder that isn't `placeholder_rvid`,
@@ -242,6 +257,9 @@ impl scc::Annotation for RegionTracker {
242257

243258
Self {
244259
representative: self.representative.min(other.representative),
260+
scc_placeholder_largest_universe: self
261+
.scc_placeholder_largest_universe
262+
.max(other.scc_placeholder_largest_universe),
245263
..self.merge_reached(other)
246264
}
247265
}
@@ -258,6 +276,7 @@ impl scc::Annotation for RegionTracker {
258276
.min(other.min_max_nameable_universe),
259277
reachable_placeholders: self.reachable_placeholders.merge(other.reachable_placeholders),
260278
representative: self.representative,
279+
scc_placeholder_largest_universe: self.scc_placeholder_largest_universe,
261280
}
262281
}
263282
}

0 commit comments

Comments
 (0)