Skip to content

Commit c7db129

Browse files
rchen152meta-codesync[bot]
authored andcommitted
Merge lower bounds before unifying vars
Summary: Variable unification preserves one of the variables and destroys the other, so make sure both have all lower bounds. For #105. Reviewed By: yangdanny97 Differential Revision: D96548067 fbshipit-source-id: e9ea002a4aa5c5aa3020768f8763372b0c3097db
1 parent 2dadc90 commit c7db129

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

pyrefly/lib/solver/solver.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,36 @@ impl<'a, Ans: LookupAnswer> Subset<'a, Ans> {
16481648
_ if got == want => Ok(()),
16491649
(Type::Var(v1), Type::Var(v2)) => {
16501650
let variables = self.solver.variables.lock();
1651+
// Variable unification is destructive, so we have to copy lower bounds first.
1652+
let root1 = variables.get_root(*v1);
1653+
let root2 = variables.get_root(*v2);
1654+
if root1 == root2 {
1655+
// same variable after unification, nothing to do
1656+
} else {
1657+
let mut v1_mut = variables.get_mut(*v1);
1658+
let mut v2_mut = variables.get_mut(*v2);
1659+
match (&mut *v1_mut, &mut *v2_mut) {
1660+
(
1661+
Variable::Quantified {
1662+
quantified: _,
1663+
lower_bounds: v1_bounds,
1664+
}
1665+
| Variable::Unwrap(v1_bounds),
1666+
Variable::Quantified {
1667+
quantified: _,
1668+
lower_bounds: v2_bounds,
1669+
}
1670+
| Variable::Unwrap(v2_bounds),
1671+
) => {
1672+
v1_bounds.extend(mem::take(v2_bounds));
1673+
*v2_bounds = v1_bounds.clone();
1674+
}
1675+
_ => {}
1676+
}
1677+
drop(v1_mut);
1678+
drop(v2_mut);
1679+
}
1680+
16511681
let variable1 = variables.get(*v1);
16521682
let variable2 = variables.get(*v2);
16531683
match (&*variable1, &*variable2) {

0 commit comments

Comments
 (0)