mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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.
This commit is contained in:
parent
228f40820d
commit
0b232d022f
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user