Rollup merge of #146717 - amandasystems:remove-placeholder-hack, r=lcnr

Clean up universe evaluation during type test evaluation

The logic was, as the removed comments suggest, hackish and meant to implement previous logic that was factored out. The new logic does exactly what the comments say, and is much less surprising.

I'm afraid we may want

r? `@lcnr`

for this one too.

I am sorry, but at least it should be easier to review.
This commit is contained in:
Matthias Krüger
2025-09-18 17:20:59 +02:00
committed by GitHub
2 changed files with 18 additions and 12 deletions
@@ -166,13 +166,9 @@ pub(crate) fn max_placeholder_universe_reached(self) -> UniverseIndex {
}
}
/// Determine if the tracked universes of the two SCCs are compatible.
pub(crate) fn universe_compatible_with(&self, other: Self) -> bool {
// HACK: We first check whether we can name the highest existential universe
// of `other`. This only exists to avoid errors in case that scc already
// depends on a placeholder it cannot name itself.
self.max_nameable_universe().can_name(other.max_nameable_universe())
|| other.reachable_placeholders.can_be_named_by(self.max_nameable_universe())
/// Determine if we can name all the placeholders in `other`.
pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool {
other.reachable_placeholders.can_be_named_by(self.max_nameable_universe.0)
}
/// If this SCC reaches a placeholder it can't name, return it.
@@ -571,11 +571,15 @@ fn propagate_constraints(&mut self) {
}
}
/// Returns `true` if all the elements in the value of `scc_b` are nameable
/// Returns `true` if all the placeholders in the value of `scc_b` are nameable
/// in `scc_a`. Used during constraint propagation, and only once
/// the value of `scc_b` has been computed.
fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool {
self.scc_annotations[scc_a].universe_compatible_with(self.scc_annotations[scc_b])
fn can_name_all_placeholders(
&self,
scc_a: ConstraintSccIndex,
scc_b: ConstraintSccIndex,
) -> bool {
self.scc_annotations[scc_a].can_name_all_placeholders(self.scc_annotations[scc_b])
}
/// Once regions have been propagated, this method is used to see
@@ -964,16 +968,22 @@ pub fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> boo
return true;
}
let fr_static = self.universal_regions().fr_static;
// If we are checking that `'sup: 'sub`, and `'sub` contains
// some placeholder that `'sup` cannot name, then this is only
// true if `'sup` outlives static.
if !self.universe_compatible(sub_region_scc, sup_region_scc) {
//
// Avoid infinite recursion if `sub_region` is already `'static`
if sub_region != fr_static
&& !self.can_name_all_placeholders(sup_region_scc, sub_region_scc)
{
debug!(
"sub universe `{sub_region_scc:?}` is not nameable \
by super `{sup_region_scc:?}`, promoting to static",
);
return self.eval_outlives(sup_region, self.universal_regions().fr_static);
return self.eval_outlives(sup_region, fr_static);
}
// Both the `sub_region` and `sup_region` consist of the union