Skip to content

Commit

Permalink
prefer universal from lower universe
Browse files Browse the repository at this point in the history
In case a variable is unified with two universal regions from different
universes, use the one with the lower universe as it has a higher chance
of being compatible with the variable.
  • Loading branch information
aliemjay committed Mar 8, 2023
1 parent 228f408 commit 0b232d0
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion compiler/rustc_middle/src/infer/unify_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,27 @@ impl<'tcx> UnifyValue for UnifiedRegion<'tcx> {
type Error = NoError;

fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
// We pick the value of the least universe because it is compatible with more variables.
// This is *not* neccessary for soundness, but it allows more region variables to be
// resolved to the said value.
#[cold]
fn min_universe<'tcx>(r1: Region<'tcx>, r2: Region<'tcx>) -> Region<'tcx> {
cmp::min_by_key(r1, r2, |r| match r.kind() {
ty::ReStatic
| ty::ReErased
| ty::ReFree(..)
| ty::ReEarlyBound(..)
| ty::ReError(_) => ty::UniverseIndex::ROOT,
ty::RePlaceholder(placeholder) => placeholder.universe,
ty::ReVar(..) | ty::ReLateBound(..) => bug!("not a universal region"),
})
}

Ok(match (value1.value, value2.value) {
// Here we can just pick one value, because the full constraints graph
// will be handled later. Ideally, we might want a `MultipleValues`
// variant or something. For now though, this is fine.
(Some(_), Some(_)) => *value1,
(Some(val1), Some(val2)) => Self { value: Some(min_universe(val1, val2)) },

(Some(_), _) => *value1,
(_, Some(_)) => *value2,
Expand Down

0 comments on commit 0b232d0

Please sign in to comment.