@@ -1759,46 +1759,44 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
1759
1759
case ConstraintKind::BindParam: {
1760
1760
if (typeVar2 && !typeVar1) {
1761
1761
// Simplify the left-hand type and perform the "occurs" check.
1762
- typeVar2 = getRepresentative (typeVar2);
1762
+ auto rep2 = getRepresentative (typeVar2);
1763
1763
type1 = simplifyType (type1, flags);
1764
1764
if (!isBindable (typeVar2, type1))
1765
1765
return formUnsolvedResult ();
1766
1766
1767
1767
if (auto *iot = type1->getAs <InOutType>()) {
1768
- assignFixedType (typeVar2, LValueType::get (iot->getObjectType ()));
1768
+ if (!rep2->getImpl ().canBindToLValue ())
1769
+ return getTypeMatchFailure (locator);
1770
+ assignFixedType (rep2, LValueType::get (iot->getObjectType ()));
1769
1771
} else {
1770
- assignFixedType (typeVar2 , type1);
1772
+ assignFixedType (rep2 , type1);
1771
1773
}
1772
1774
return getTypeMatchSuccess ();
1773
1775
} else if (typeVar1 && !typeVar2) {
1774
1776
// Simplify the right-hand type and perform the "occurs" check.
1775
- typeVar1 = getRepresentative (typeVar1);
1777
+ auto rep1 = getRepresentative (typeVar1);
1776
1778
type2 = simplifyType (type2, flags);
1777
- if (!isBindable (typeVar1 , type2))
1779
+ if (!isBindable (rep1 , type2))
1778
1780
return formUnsolvedResult ();
1779
1781
1780
- // If the right-hand side of the BindParam constraint
1781
- // is `lvalue` type, we'll have to make sure that
1782
- // left-hand side is bound to type variable which
1783
- // is wrapped in `inout` type to preserve inout/lvalue pairing.
1784
1782
if (auto *lvt = type2->getAs <LValueType>()) {
1785
- auto *tv = createTypeVariable (typeVar1 ->getImpl ().getLocator ());
1786
- assignFixedType (typeVar1, InOutType::get (tv) );
1787
-
1788
- typeVar1 = tv;
1789
- type2 = lvt-> getObjectType ( );
1783
+ if (!rep1 ->getImpl ().canBindToInOut ())
1784
+ return getTypeMatchFailure (locator );
1785
+ assignFixedType (rep1, InOutType::get (lvt-> getObjectType ()));
1786
+ } else {
1787
+ assignFixedType (rep1, type2 );
1790
1788
}
1791
-
1792
- // If we have a binding for the right-hand side
1793
- // (argument type used in the body) don't try
1794
- // to bind it to the left-hand side (parameter type)
1795
- // directly, because there could be an implicit
1796
- // conversion between them, and actual binding
1797
- // can only come from the left-hand side.
1798
- addUnsolvedConstraint (
1799
- Constraint::create (*this , ConstraintKind::Equal, typeVar1, type2,
1800
- getConstraintLocator (locator)));
1801
1789
return getTypeMatchSuccess ();
1790
+ } if (typeVar1 && typeVar2) {
1791
+ auto rep1 = getRepresentative (typeVar1);
1792
+ auto rep2 = getRepresentative (typeVar2);
1793
+
1794
+ if (!rep1->getImpl ().canBindToInOut () ||
1795
+ !rep2->getImpl ().canBindToLValue ()) {
1796
+ // Merge the equivalence classes corresponding to these two variables.
1797
+ mergeEquivalenceClasses (rep1, rep2);
1798
+ return getTypeMatchSuccess ();
1799
+ }
1802
1800
}
1803
1801
1804
1802
return formUnsolvedResult ();
0 commit comments