Skip to content

Commit 566bc49

Browse files
committed
Fix issue with swapping in Unifier::unifyField()
1 parent 3a93952 commit 566bc49

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

src/Checker.cc

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,9 +1347,9 @@ namespace bolt {
13471347
return Constraint->Source;
13481348
}
13491349

1350-
bool unify(Type* A, Type* B, bool DidSwap);
1350+
bool unifyField(Type* A, Type* B, bool DidSwap);
13511351

1352-
bool unifyField(Type* A, Type* B);
1352+
bool unify(Type* A, Type* B, bool DidSwap);
13531353

13541354
bool unify() {
13551355
return unify(Constraint->Left, Constraint->Right, false);
@@ -1468,6 +1468,24 @@ namespace bolt {
14681468

14691469
};
14701470

1471+
bool Unifier::unifyField(Type* A, Type* B, bool DidSwap) {
1472+
if (llvm::isa<TAbsent>(A) && llvm::isa<TAbsent>(B)) {
1473+
return true;
1474+
}
1475+
if (llvm::isa<TAbsent>(B)) {
1476+
std::swap(A, B);
1477+
DidSwap = !DidSwap;
1478+
}
1479+
if (llvm::isa<TAbsent>(A)) {
1480+
auto Present = static_cast<TPresent*>(B);
1481+
C.DE.add<FieldNotFoundDiagnostic>(CurrentFieldName, C.simplifyType(getLeft()), LeftPath, getSource());
1482+
return false;
1483+
}
1484+
auto Present1 = static_cast<TPresent*>(A);
1485+
auto Present2 = static_cast<TPresent*>(B);
1486+
return unify(Present1->Ty, Present2->Ty, DidSwap);
1487+
};
1488+
14711489
bool Unifier::unify(Type* A, Type* B, bool DidSwap) {
14721490

14731491
A = C.simplifyType(A);
@@ -1520,23 +1538,6 @@ namespace bolt {
15201538
DidSwap = !DidSwap;
15211539
};
15221540

1523-
auto unifyField = [&](Type* A, Type* B) {
1524-
if (llvm::isa<TAbsent>(A) && llvm::isa<TAbsent>(B)) {
1525-
return true;
1526-
}
1527-
if (llvm::isa<TAbsent>(B)) {
1528-
swap();
1529-
}
1530-
if (llvm::isa<TAbsent>(A)) {
1531-
auto Present = static_cast<TPresent*>(B);
1532-
C.DE.add<FieldNotFoundDiagnostic>(CurrentFieldName, C.simplifyType(getLeft()), LeftPath, getSource());
1533-
return false;
1534-
}
1535-
auto Present1 = static_cast<TPresent*>(A);
1536-
auto Present2 = static_cast<TPresent*>(B);
1537-
return unify(Present1->Ty, Present2->Ty, DidSwap);
1538-
};
1539-
15401541
if (llvm::isa<TVar>(A) && llvm::isa<TVar>(B)) {
15411542
auto Var1 = static_cast<TVar*>(A);
15421543
auto Var2 = static_cast<TVar*>(B);
@@ -1706,7 +1707,7 @@ namespace bolt {
17061707
LeftPath.push_back(TypeIndex::forFieldType());
17071708
RightPath.push_back(TypeIndex::forFieldType());
17081709
CurrentFieldName = Field1->Name;
1709-
if (!unifyField(Field1->Ty, Field2->Ty)) {
1710+
if (!unifyField(Field1->Ty, Field2->Ty, DidSwap)) {
17101711
Success = false;
17111712
}
17121713
LeftPath.pop_back();
@@ -1743,7 +1744,7 @@ namespace bolt {
17431744
bool Success = true;
17441745
pushLeft(TypeIndex::forFieldType());
17451746
CurrentFieldName = Field->Name;
1746-
if (!unifyField(Field->Ty, new TAbsent)) {
1747+
if (!unifyField(Field->Ty, new TAbsent, DidSwap)) {
17471748
Success = false;
17481749
}
17491750
popLeft();

0 commit comments

Comments
 (0)