Skip to content

Commit 0b232d0

Browse files
committed
prefer universal from lower universe
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.
1 parent 228f408 commit 0b232d0

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

compiler/rustc_middle/src/infer/unify_key.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,27 @@ impl<'tcx> UnifyValue for UnifiedRegion<'tcx> {
5757
type Error = NoError;
5858

5959
fn unify_values(value1: &Self, value2: &Self) -> Result<Self, NoError> {
60+
// We pick the value of the least universe because it is compatible with more variables.
61+
// This is *not* neccessary for soundness, but it allows more region variables to be
62+
// resolved to the said value.
63+
#[cold]
64+
fn min_universe<'tcx>(r1: Region<'tcx>, r2: Region<'tcx>) -> Region<'tcx> {
65+
cmp::min_by_key(r1, r2, |r| match r.kind() {
66+
ty::ReStatic
67+
| ty::ReErased
68+
| ty::ReFree(..)
69+
| ty::ReEarlyBound(..)
70+
| ty::ReError(_) => ty::UniverseIndex::ROOT,
71+
ty::RePlaceholder(placeholder) => placeholder.universe,
72+
ty::ReVar(..) | ty::ReLateBound(..) => bug!("not a universal region"),
73+
})
74+
}
75+
6076
Ok(match (value1.value, value2.value) {
6177
// Here we can just pick one value, because the full constraints graph
6278
// will be handled later. Ideally, we might want a `MultipleValues`
6379
// variant or something. For now though, this is fine.
64-
(Some(_), Some(_)) => *value1,
80+
(Some(val1), Some(val2)) => Self { value: Some(min_universe(val1, val2)) },
6581

6682
(Some(_), _) => *value1,
6783
(_, Some(_)) => *value2,

0 commit comments

Comments
 (0)