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.
This commit is contained in:
Amanda Stjerna 2025-09-18 13:11:37 +02:00
parent 5e33838cca
commit 2ed5373293
2 changed files with 18 additions and 12 deletions

View File

@ -166,13 +166,9 @@ impl RegionTracker {
}
}
/// 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.

View File

@ -571,11 +571,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}
/// 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 @@ impl<'tcx> RegionInferenceContext<'tcx> {
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