Skip to content

Commit 351a854

Browse files
committed
Be more restrictive of when we add placeholder-existential errors
1 parent 0c26245 commit 351a854

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

@@ -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

Comments
 (0)