Fix issue with swapping in Unifier::unifyField()
This commit is contained in:
parent
3a93952b36
commit
566bc497f3
1 changed files with 22 additions and 21 deletions
|
@ -1347,9 +1347,9 @@ namespace bolt {
|
||||||
return Constraint->Source;
|
return Constraint->Source;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unify(Type* A, Type* B, bool DidSwap);
|
bool unifyField(Type* A, Type* B, bool DidSwap);
|
||||||
|
|
||||||
bool unifyField(Type* A, Type* B);
|
bool unify(Type* A, Type* B, bool DidSwap);
|
||||||
|
|
||||||
bool unify() {
|
bool unify() {
|
||||||
return unify(Constraint->Left, Constraint->Right, false);
|
return unify(Constraint->Left, Constraint->Right, false);
|
||||||
|
@ -1468,6 +1468,24 @@ namespace bolt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool Unifier::unifyField(Type* A, Type* B, bool DidSwap) {
|
||||||
|
if (llvm::isa<TAbsent>(A) && llvm::isa<TAbsent>(B)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (llvm::isa<TAbsent>(B)) {
|
||||||
|
std::swap(A, B);
|
||||||
|
DidSwap = !DidSwap;
|
||||||
|
}
|
||||||
|
if (llvm::isa<TAbsent>(A)) {
|
||||||
|
auto Present = static_cast<TPresent*>(B);
|
||||||
|
C.DE.add<FieldNotFoundDiagnostic>(CurrentFieldName, C.simplifyType(getLeft()), LeftPath, getSource());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto Present1 = static_cast<TPresent*>(A);
|
||||||
|
auto Present2 = static_cast<TPresent*>(B);
|
||||||
|
return unify(Present1->Ty, Present2->Ty, DidSwap);
|
||||||
|
};
|
||||||
|
|
||||||
bool Unifier::unify(Type* A, Type* B, bool DidSwap) {
|
bool Unifier::unify(Type* A, Type* B, bool DidSwap) {
|
||||||
|
|
||||||
A = C.simplifyType(A);
|
A = C.simplifyType(A);
|
||||||
|
@ -1520,23 +1538,6 @@ namespace bolt {
|
||||||
DidSwap = !DidSwap;
|
DidSwap = !DidSwap;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto unifyField = [&](Type* A, Type* B) {
|
|
||||||
if (llvm::isa<TAbsent>(A) && llvm::isa<TAbsent>(B)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (llvm::isa<TAbsent>(B)) {
|
|
||||||
swap();
|
|
||||||
}
|
|
||||||
if (llvm::isa<TAbsent>(A)) {
|
|
||||||
auto Present = static_cast<TPresent*>(B);
|
|
||||||
C.DE.add<FieldNotFoundDiagnostic>(CurrentFieldName, C.simplifyType(getLeft()), LeftPath, getSource());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto Present1 = static_cast<TPresent*>(A);
|
|
||||||
auto Present2 = static_cast<TPresent*>(B);
|
|
||||||
return unify(Present1->Ty, Present2->Ty, DidSwap);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (llvm::isa<TVar>(A) && llvm::isa<TVar>(B)) {
|
if (llvm::isa<TVar>(A) && llvm::isa<TVar>(B)) {
|
||||||
auto Var1 = static_cast<TVar*>(A);
|
auto Var1 = static_cast<TVar*>(A);
|
||||||
auto Var2 = static_cast<TVar*>(B);
|
auto Var2 = static_cast<TVar*>(B);
|
||||||
|
@ -1706,7 +1707,7 @@ namespace bolt {
|
||||||
LeftPath.push_back(TypeIndex::forFieldType());
|
LeftPath.push_back(TypeIndex::forFieldType());
|
||||||
RightPath.push_back(TypeIndex::forFieldType());
|
RightPath.push_back(TypeIndex::forFieldType());
|
||||||
CurrentFieldName = Field1->Name;
|
CurrentFieldName = Field1->Name;
|
||||||
if (!unifyField(Field1->Ty, Field2->Ty)) {
|
if (!unifyField(Field1->Ty, Field2->Ty, DidSwap)) {
|
||||||
Success = false;
|
Success = false;
|
||||||
}
|
}
|
||||||
LeftPath.pop_back();
|
LeftPath.pop_back();
|
||||||
|
@ -1743,7 +1744,7 @@ namespace bolt {
|
||||||
bool Success = true;
|
bool Success = true;
|
||||||
pushLeft(TypeIndex::forFieldType());
|
pushLeft(TypeIndex::forFieldType());
|
||||||
CurrentFieldName = Field->Name;
|
CurrentFieldName = Field->Name;
|
||||||
if (!unifyField(Field->Ty, new TAbsent)) {
|
if (!unifyField(Field->Ty, new TAbsent, DidSwap)) {
|
||||||
Success = false;
|
Success = false;
|
||||||
}
|
}
|
||||||
popLeft();
|
popLeft();
|
||||||
|
|
Loading…
Reference in a new issue