Skip to content

Commit 97647ff

Browse files
committed
Only flag the error for placeholder-existential failures if there is
actually an existential.
1 parent 807a443 commit 97647ff

File tree

3 files changed

+46
-31
lines changed

3 files changed

+46
-31
lines changed

compiler/rustc_borrowck/src/handle_placeholders.rs

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::ty::VarianceDiagInfo;
2020
use crate::type_check::free_region_relations::UniversalRegionRelations;
2121
use crate::type_check::{Locations, MirTypeckRegionConstraints};
2222
use crate::universal_regions::UniversalRegions;
23-
use crate::{BorrowckInferCtxt, NllRegionVariableOrigin, bug};
23+
use crate::{BorrowckInferCtxt, NllRegionVariableOrigin};
2424

2525
/// A set of outlives constraints after rewriting to remove
2626
/// higher-kinded constraints.
@@ -122,10 +122,12 @@ impl PlaceholderReachability {
122122
pub(crate) struct RegionTracker {
123123
reachable_placeholders: PlaceholderReachability,
124124

125-
/// The largest universe nameable from this SCC.
126-
/// It is the smallest nameable universes of all
127-
/// existential regions reachable from it. Small Rvids are preferred.
128-
max_nameable_universe: (UniverseIndex, RegionVid),
125+
/// The smallest max nameable universe of all
126+
/// regions reachable from this SCC.
127+
min_max_nameable_universe: UniverseIndex,
128+
129+
/// The existential region with the smallest universe, if any.
130+
min_universe_existential: Option<(UniverseIndex, RegionVid)>,
129131

130132
/// The representative Region Variable Id for this SCC.
131133
pub(crate) representative: Representative,
@@ -146,7 +148,15 @@ impl RegionTracker {
146148

147149
Self {
148150
reachable_placeholders,
149-
max_nameable_universe: (definition.universe, rvid),
151+
min_universe_existential: if matches!(
152+
definition.origin,
153+
NllRegionVariableOrigin::Existential { .. }
154+
) {
155+
Some((definition.universe, rvid))
156+
} else {
157+
None
158+
},
159+
min_max_nameable_universe: definition.universe,
150160
representative: Representative::new(rvid, definition),
151161
}
152162
}
@@ -155,7 +165,8 @@ impl RegionTracker {
155165
/// largest nameable universe of any reachable region, or
156166
/// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)`
157167
pub(crate) fn max_nameable_universe(self) -> UniverseIndex {
158-
self.max_nameable_universe.0
168+
// Note that this is stricter than it might need to be!
169+
self.min_max_nameable_universe
159170
}
160171

161172
pub(crate) fn max_placeholder_universe_reached(self) -> UniverseIndex {
@@ -168,13 +179,13 @@ impl RegionTracker {
168179

169180
/// Determine if we can name all the placeholders in `other`.
170181
pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool {
171-
other.reachable_placeholders.can_be_named_by(self.max_nameable_universe.0)
182+
other.reachable_placeholders.can_be_named_by(self.min_max_nameable_universe)
172183
}
173184

174185
/// If this SCC reaches a placeholder it can't name, return it.
175186
fn unnameable_placeholder(&self) -> Option<(UniverseIndex, RegionVid)> {
176187
self.reachable_placeholders.max_universe().filter(|&(placeholder_universe, _)| {
177-
!self.max_nameable_universe().can_name(placeholder_universe)
188+
!self.min_max_nameable_universe.can_name(placeholder_universe)
178189
})
179190
}
180191

@@ -189,7 +200,12 @@ impl RegionTracker {
189200
return None;
190201
};
191202

192-
let (reachable_lowest_max_u, reachable_lowest_max_u_rvid) = self.max_nameable_universe;
203+
let Some((reachable_lowest_max_u, reachable_lowest_max_u_rvid)) =
204+
self.min_universe_existential
205+
else {
206+
debug!("SCC universe wasn't lowered by an existential; skipping.");
207+
return None;
208+
};
193209

194210
(!self.reachable_placeholders.can_be_named_by(reachable_lowest_max_u))
195211
.then_some(reachable_lowest_max_u_rvid)
@@ -222,14 +238,20 @@ impl scc::Annotation for RegionTracker {
222238

223239
Self {
224240
representative: self.representative.min(other.representative),
225-
max_nameable_universe: self.max_nameable_universe.min(other.max_nameable_universe),
226-
reachable_placeholders: self.reachable_placeholders.merge(other.reachable_placeholders),
241+
..self.merge_reached(other)
227242
}
228243
}
229244

245+
#[inline(always)]
230246
fn merge_reached(self, other: Self) -> Self {
231247
Self {
232-
max_nameable_universe: self.max_nameable_universe.min(other.max_nameable_universe),
248+
min_universe_existential: self
249+
.min_universe_existential
250+
.xor(other.min_universe_existential)
251+
.or_else(|| self.min_universe_existential.min(other.min_universe_existential)),
252+
min_max_nameable_universe: self
253+
.min_max_nameable_universe
254+
.min(other.min_max_nameable_universe),
233255
reachable_placeholders: self.reachable_placeholders.merge(other.reachable_placeholders),
234256
representative: self.representative,
235257
}
@@ -438,19 +460,7 @@ fn rewrite_placeholder_outlives<'tcx>(
438460
variance_info: VarianceDiagInfo::None,
439461
from_closure: false,
440462
});
441-
} else if !(annotation.reaches_existential_that_cannot_name_us().is_some()
442-
|| annotation.reaches_other_placeholder(annotation.representative.rvid()).is_some())
443-
{
444-
// The SCC's representative is not nameable from some region
445-
// that ends up in the SCC. This means there is nothing for us to do.
446-
// However, this is only possible under circumstances that produce
447-
// errors, so we make sure that we catch them here. Otherwise,
448-
// there might actually be soundness issues!
449-
bug!(
450-
"Universe of SCC {scc:?} should have been lowered by an existential or at least another placeholder but was lowered by {:?}, which is neither.",
451-
annotation.max_nameable_universe
452-
);
453-
};
463+
}
454464
}
455465
added_constraints
456466
}
@@ -482,12 +492,12 @@ fn find_placeholder_mismatch_errors<'tcx>(
482492
let scc = sccs.scc(rvid);
483493
let annotation = annotations.scc_to_annotation[scc];
484494

485-
if let Some(existential_that_cannot_name_rvid) =
486-
annotation.reaches_existential_that_cannot_name_us()
487-
{
495+
if let Some(cannot_name_rvid) = annotation.reaches_existential_that_cannot_name_us() {
496+
debug!("Existential {cannot_name_rvid:?} lowered our universe...");
497+
488498
errors_buffer.push(RegionErrorKind::PlaceholderOutlivesExistentialThatCannotNameIt {
489499
longer_fr: rvid,
490-
existential_that_cannot_name_longer: existential_that_cannot_name_rvid,
500+
existential_that_cannot_name_longer: cannot_name_rvid,
491501
placeholder: origin_a,
492502
})
493503
}

compiler/rustc_borrowck/src/nll.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ pub(crate) fn compute_regions<'tcx>(
136136
&mut placeholder_errors,
137137
);
138138

139+
debug!("Placeholder errors: {placeholder_errors:?}");
140+
139141
// If requested, emit legacy polonius facts.
140142
polonius::legacy::emit_facts(
141143
&mut polonius_facts,
@@ -188,6 +190,7 @@ pub(crate) fn compute_regions<'tcx>(
188190

189191
let nll_errors = if region_inference_errors.is_empty() {
190192
// Only flag the higher-kinded bounds errors if there are no borrowck errors.
193+
debug!("No region inference errors, using placeholder errors: {placeholder_errors:?}");
191194
placeholder_errors
192195
} else {
193196
debug!("Errors already reported, skipping these: {placeholder_errors:?}");

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15761576
from_region_origin: NllRegionVariableOrigin,
15771577
to_region: RegionVid,
15781578
) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) {
1579-
assert!(from_region != to_region, "Trying to blame a region for itself!");
1579+
if from_region == to_region {
1580+
bug!("Trying to blame {from_region:?} for itself!");
1581+
}
15801582

15811583
let path = self.constraint_path_between_regions(from_region, to_region).unwrap();
15821584

0 commit comments

Comments
 (0)