Switch to field constraints instead of TTupleIndex
This commit is contained in:
parent
4ab4094acc
commit
3942004f76
6 changed files with 103 additions and 193 deletions
|
@ -1,8 +1,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "zen/config.hpp"
|
||||
|
||||
#include "bolt/ByteString.hpp"
|
||||
#include "bolt/Common.hpp"
|
||||
#include "bolt/CST.hpp"
|
||||
|
@ -11,7 +9,6 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
|
@ -77,6 +74,7 @@ namespace bolt {
|
|||
|
||||
enum class ConstraintKind {
|
||||
Equal,
|
||||
Field,
|
||||
Many,
|
||||
Empty,
|
||||
};
|
||||
|
@ -112,6 +110,19 @@ namespace bolt {
|
|||
|
||||
};
|
||||
|
||||
class CField : public Constraint {
|
||||
public:
|
||||
|
||||
Type* TupleTy;
|
||||
size_t I;
|
||||
Type* FieldTy;
|
||||
Node* Source;
|
||||
|
||||
inline CField(Type* TupleTy, size_t I, Type* FieldTy, Node* Source = nullptr):
|
||||
Constraint(ConstraintKind::Field), TupleTy(TupleTy), I(I), FieldTy(FieldTy), Source(Source) {}
|
||||
|
||||
};
|
||||
|
||||
class CMany : public Constraint {
|
||||
public:
|
||||
|
||||
|
@ -254,7 +265,7 @@ namespace bolt {
|
|||
*/
|
||||
std::deque<class Constraint*> Queue;
|
||||
|
||||
void solveEqual(CEqual* C);
|
||||
void unify(Type* Left, Type* Right, Node* Source);
|
||||
|
||||
void solve(Constraint* Constraint);
|
||||
|
||||
|
@ -276,11 +287,6 @@ namespace bolt {
|
|||
|
||||
Checker(const LanguageConfig& Config, DiagnosticEngine& DE);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*/
|
||||
Type* simplifyType(Type* Ty);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*/
|
||||
|
|
|
@ -170,9 +170,14 @@ namespace bolt {
|
|||
|
||||
Type* Tuple;
|
||||
std::size_t I;
|
||||
Node* Source;
|
||||
|
||||
inline TupleIndexOutOfRangeDiagnostic(Type* Tuple, std::size_t I):
|
||||
Diagnostic(DiagnosticKind::TupleIndexOutOfRange), Tuple(Tuple), I(I) {}
|
||||
inline TupleIndexOutOfRangeDiagnostic(Type* Tuple, std::size_t I, Node* Source):
|
||||
Diagnostic(DiagnosticKind::TupleIndexOutOfRange), Tuple(Tuple), I(I), Source(Source) {}
|
||||
|
||||
inline Node * getNode() const override {
|
||||
return Source;
|
||||
}
|
||||
|
||||
unsigned getCode() const noexcept override {
|
||||
return 2015;
|
||||
|
@ -221,9 +226,14 @@ namespace bolt {
|
|||
public:
|
||||
|
||||
Type* Ty;
|
||||
Node* Source;
|
||||
|
||||
inline NotATupleDiagnostic(Type* Ty):
|
||||
Diagnostic(DiagnosticKind::NotATuple), Ty(Ty) {}
|
||||
inline NotATupleDiagnostic(Type* Ty, Node* Source):
|
||||
Diagnostic(DiagnosticKind::NotATuple), Ty(Ty), Source(Source) {}
|
||||
|
||||
inline Node * getNode() const override {
|
||||
return Source;
|
||||
}
|
||||
|
||||
unsigned getCode() const noexcept override {
|
||||
return 2016;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <vector>
|
||||
|
||||
#include "zen/config.hpp"
|
||||
#include "zen/range.hpp"
|
||||
|
||||
#include "bolt/CST.hpp"
|
||||
#include "bolt/ByteString.hpp"
|
||||
|
@ -48,7 +47,6 @@ namespace bolt {
|
|||
TupleElement,
|
||||
FieldType,
|
||||
FieldRestType,
|
||||
TupleIndexType,
|
||||
PresentType,
|
||||
End,
|
||||
};
|
||||
|
@ -105,10 +103,6 @@ namespace bolt {
|
|||
return { TypeIndexKind::AppArgType };
|
||||
}
|
||||
|
||||
static TypeIndex forTupleIndexType() {
|
||||
return { TypeIndexKind::TupleIndexType };
|
||||
}
|
||||
|
||||
static TypeIndex forPresentType() {
|
||||
return { TypeIndexKind::PresentType };
|
||||
}
|
||||
|
@ -157,7 +151,6 @@ namespace bolt {
|
|||
App,
|
||||
Arrow,
|
||||
Tuple,
|
||||
TupleIndex,
|
||||
Field,
|
||||
Nil,
|
||||
Absent,
|
||||
|
@ -225,15 +218,6 @@ namespace bolt {
|
|||
|
||||
};
|
||||
|
||||
struct TTupleIndex {
|
||||
|
||||
Type* Ty;
|
||||
std::size_t I;
|
||||
|
||||
bool operator==(const TTupleIndex& Other) const;
|
||||
|
||||
};
|
||||
|
||||
struct TNil {
|
||||
bool operator==(const TNil& Other) const;
|
||||
};
|
||||
|
@ -266,7 +250,6 @@ namespace bolt {
|
|||
TVar Var;
|
||||
TArrow Arrow;
|
||||
TTuple Tuple;
|
||||
TTupleIndex TupleIndex;
|
||||
TNil Nil;
|
||||
TField Field;
|
||||
TAbsent Absent;
|
||||
|
@ -288,9 +271,6 @@ namespace bolt {
|
|||
Type(TTuple&& Tuple):
|
||||
Kind(TypeKind::Tuple), Tuple(std::move(Tuple)) {};
|
||||
|
||||
Type(TTupleIndex&& TupleIndex):
|
||||
Kind(TypeKind::TupleIndex), TupleIndex(std::move(TupleIndex)) {};
|
||||
|
||||
Type(TNil&& Nil):
|
||||
Kind(TypeKind::Nil), Nil(std::move(Nil)) {};
|
||||
|
||||
|
@ -303,46 +283,6 @@ namespace bolt {
|
|||
Type(TPresent&& Present):
|
||||
Kind(TypeKind::Present), Present(std::move(Present)) {};
|
||||
|
||||
// Type(TCon Con): Kind(TypeKind::Con) {
|
||||
// new (&Con)TCon(Con);
|
||||
// }
|
||||
|
||||
// Type(TApp App): Kind(TypeKind::App) {
|
||||
// new (&App)TApp(App);
|
||||
// }
|
||||
|
||||
// Type(TVar Var): Kind(TypeKind::Var) {
|
||||
// new (&Var)TVar(Var);
|
||||
// }
|
||||
|
||||
// Type(TArrow Arrow): Kind(TypeKind::Arrow) {
|
||||
// new (&Arrow)TArrow(Arrow);
|
||||
// }
|
||||
|
||||
// Type(TTuple Tuple): Kind(TypeKind::Tuple) {
|
||||
// new (&Tuple)TTuple(Tuple);
|
||||
// }
|
||||
|
||||
// Type(TTupleIndex TupleIndex): Kind(TypeKind::TupleIndex) {
|
||||
// new (&TupleIndex)TTupleIndex(TupleIndex);
|
||||
// }
|
||||
|
||||
// Type(TNil Nil): Kind(TypeKind::Nil) {
|
||||
// new (&Nil)TNil(Nil);
|
||||
// }
|
||||
|
||||
// Type(TField Field): Kind(TypeKind::Field) {
|
||||
// new (&Field)TField(Field);
|
||||
// }
|
||||
|
||||
// Type(TAbsent Absent): Kind(TypeKind::Absent) {
|
||||
// new (&Absent)TAbsent(Absent);
|
||||
// }
|
||||
|
||||
// Type(TPresent Present): Kind(TypeKind::Present) {
|
||||
// new (&Present)TPresent(Present);
|
||||
// }
|
||||
|
||||
Type(const Type& Other): Kind(Other.Kind) {
|
||||
switch (Kind) {
|
||||
case TypeKind::Con:
|
||||
|
@ -360,9 +300,6 @@ namespace bolt {
|
|||
case TypeKind::Tuple:
|
||||
new (&Tuple)TTuple(Other.Tuple);
|
||||
break;
|
||||
case TypeKind::TupleIndex:
|
||||
new (&TupleIndex)TTupleIndex(Other.TupleIndex);
|
||||
break;
|
||||
case TypeKind::Nil:
|
||||
new (&Nil)TNil(Other.Nil);
|
||||
break;
|
||||
|
@ -395,9 +332,6 @@ namespace bolt {
|
|||
case TypeKind::Tuple:
|
||||
new (&Tuple)TTuple(std::move(Other.Tuple));
|
||||
break;
|
||||
case TypeKind::TupleIndex:
|
||||
new (&TupleIndex)TTupleIndex(std::move(Other.TupleIndex));
|
||||
break;
|
||||
case TypeKind::Nil:
|
||||
new (&Nil)TNil(std::move(Other.Nil));
|
||||
break;
|
||||
|
@ -492,20 +426,6 @@ namespace bolt {
|
|||
return Tuple;
|
||||
}
|
||||
|
||||
bool isTupleIndex() const {
|
||||
return Kind == TypeKind::TupleIndex;
|
||||
}
|
||||
|
||||
TTupleIndex& asTupleIndex() {
|
||||
ZEN_ASSERT(Kind == TypeKind::TupleIndex);
|
||||
return TupleIndex;
|
||||
}
|
||||
|
||||
const TTupleIndex& asTupleIndex() const {
|
||||
ZEN_ASSERT(Kind == TypeKind::TupleIndex);
|
||||
return TupleIndex;
|
||||
}
|
||||
|
||||
bool isField() const {
|
||||
return Kind == TypeKind::Field;
|
||||
}
|
||||
|
@ -611,9 +531,6 @@ namespace bolt {
|
|||
case TypeKind::Tuple:
|
||||
Tuple.~TTuple();
|
||||
break;
|
||||
case TypeKind::TupleIndex:
|
||||
TupleIndex.~TTupleIndex();
|
||||
break;
|
||||
case TypeKind::Nil:
|
||||
Nil.~TNil();
|
||||
break;
|
||||
|
@ -648,9 +565,6 @@ namespace bolt {
|
|||
case TypeKind::Tuple:
|
||||
Tuple = Other.Tuple;
|
||||
break;
|
||||
case TypeKind::TupleIndex:
|
||||
TupleIndex = Other.TupleIndex;
|
||||
break;
|
||||
case TypeKind::Nil:
|
||||
Nil = Other.Nil;
|
||||
break;
|
||||
|
@ -735,10 +649,6 @@ namespace bolt {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visitTupleIndexType(C<TTupleIndex>& Ty) {
|
||||
visit(Ty.Ty);
|
||||
}
|
||||
|
||||
virtual void visitAbsentType(C<TAbsent>& Ty) {
|
||||
}
|
||||
|
||||
|
@ -794,12 +704,6 @@ namespace bolt {
|
|||
visit(Present->Ty);
|
||||
break;
|
||||
}
|
||||
case TypeKind::TupleIndex:
|
||||
{
|
||||
auto& Index = Ty->asTupleIndex();
|
||||
visit(Index->Ty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -837,9 +741,6 @@ namespace bolt {
|
|||
case TypeKind::App:
|
||||
visitAppType(Ty->asApp());
|
||||
break;
|
||||
case TypeKind::TupleIndex:
|
||||
visitTupleIndexType(Ty->asTupleIndex());
|
||||
break;
|
||||
}
|
||||
exitType(Ty);
|
||||
}
|
||||
|
|
|
@ -30,37 +30,20 @@ namespace bolt {
|
|||
}
|
||||
return new CMany(*NewConstraints);
|
||||
}
|
||||
case ConstraintKind::Field:
|
||||
{
|
||||
auto Field = static_cast<CField*>(this);
|
||||
auto NewTupleTy = Field->TupleTy->substitute(Sub);
|
||||
auto NewFieldTy = Field->FieldTy->substitute(Sub);
|
||||
return new CField(NewTupleTy, Field->I, NewFieldTy);
|
||||
}
|
||||
case ConstraintKind::Empty:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Type* Checker::simplifyType(Type* Ty) {
|
||||
|
||||
Ty = Ty->find();
|
||||
|
||||
if (Ty->isTupleIndex()) {
|
||||
auto& Index = Ty->asTupleIndex();
|
||||
auto MaybeTuple = simplifyType(Index.Ty);
|
||||
if (MaybeTuple->isTuple()) {
|
||||
auto& Tuple = MaybeTuple->asTuple();
|
||||
if (Index.I >= Tuple.ElementTypes.size()) {
|
||||
DE.add<TupleIndexOutOfRangeDiagnostic>(MaybeTuple, Index.I);
|
||||
} else {
|
||||
auto ElementTy = simplifyType(Tuple.ElementTypes[Index.I]);
|
||||
Ty->set(ElementTy);
|
||||
Ty = ElementTy;
|
||||
}
|
||||
} else if (!MaybeTuple->isVar()) {
|
||||
DE.add<NotATupleDiagnostic>(MaybeTuple);
|
||||
}
|
||||
}
|
||||
|
||||
return Ty;
|
||||
}
|
||||
|
||||
Type* Checker::solveType(Type* Ty) {
|
||||
return Ty->rewrite([this](auto Ty) { return simplifyType(Ty); }, true);
|
||||
return Ty->rewrite([this](auto Ty) { return Ty->find(); }, true);
|
||||
}
|
||||
|
||||
Checker::Checker(const LanguageConfig& Config, DiagnosticEngine& DE):
|
||||
|
@ -135,7 +118,14 @@ namespace bolt {
|
|||
}
|
||||
|
||||
void Checker::addConstraint(Constraint* C) {
|
||||
|
||||
switch (C->getKind()) {
|
||||
|
||||
case ConstraintKind::Field:
|
||||
// FIXME Check if this is all that needs to be done
|
||||
getContext().Constraints->push_back(C);
|
||||
break;
|
||||
|
||||
case ConstraintKind::Equal:
|
||||
{
|
||||
auto Y = static_cast<CEqual*>(C);
|
||||
|
@ -195,13 +185,14 @@ namespace bolt {
|
|||
}
|
||||
|
||||
if (UpperLevel == LowerLevel || MaxLevelLeft == Global || MaxLevelRight == Global) {
|
||||
solveEqual(Y);
|
||||
unify(Y->Left, Y->Right, Y->Source);
|
||||
} else {
|
||||
Contexts[UpperLevel]->Constraints->push_back(C);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConstraintKind::Many:
|
||||
{
|
||||
auto Y = static_cast<CMany*>(C);
|
||||
|
@ -210,9 +201,12 @@ namespace bolt {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ConstraintKind::Empty:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Checker::forwardDeclare(Node* X) {
|
||||
|
@ -1061,7 +1055,8 @@ namespace bolt {
|
|||
case NodeKind::IntegerLiteral:
|
||||
{
|
||||
auto I = static_cast<IntegerLiteral*>(Member->Name);
|
||||
Ty = new Type(TTupleIndex(ExprTy, I->getInteger()));
|
||||
Ty = createTypeVar();
|
||||
addConstraint(new CField(ExprTy, I->asInt(), Ty, Member));
|
||||
break;
|
||||
}
|
||||
case NodeKind::Identifier:
|
||||
|
@ -1310,6 +1305,26 @@ namespace bolt {
|
|||
case ConstraintKind::Empty:
|
||||
break;
|
||||
|
||||
case ConstraintKind::Field:
|
||||
{
|
||||
auto Field = static_cast<CField*>(Constraint);
|
||||
auto MaybeTuple = Field->TupleTy->find();
|
||||
if (MaybeTuple->isTuple()) {
|
||||
auto& Tuple = MaybeTuple->asTuple();
|
||||
if (Field->I >= Tuple.ElementTypes.size()) {
|
||||
DE.add<TupleIndexOutOfRangeDiagnostic>(MaybeTuple, Field->I, Field->Source);
|
||||
} else {
|
||||
auto ElementTy = Tuple.ElementTypes[Field->I];
|
||||
unify(ElementTy, Field->FieldTy, Field->Source);
|
||||
}
|
||||
} else if (MaybeTuple->isVar()) {
|
||||
// TODO Add logic for when tuple is a var
|
||||
} else {
|
||||
DE.add<NotATupleDiagnostic>(MaybeTuple, Field->Source);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ConstraintKind::Many:
|
||||
{
|
||||
auto Many = static_cast<CMany*>(Constraint);
|
||||
|
@ -1321,7 +1336,8 @@ namespace bolt {
|
|||
|
||||
case ConstraintKind::Equal:
|
||||
{
|
||||
solveEqual(static_cast<CEqual*>(Constraint));
|
||||
auto Equal = static_cast<CEqual*>(Constraint);
|
||||
unify(Equal->Left, Equal->Right, Equal->Source);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1392,7 +1408,11 @@ namespace bolt {
|
|||
struct Unifier {
|
||||
|
||||
Checker& C;
|
||||
CEqual* Constraint;
|
||||
// CEqual* Constraint;
|
||||
Type* Left;
|
||||
Type* Right;
|
||||
Node* Source;
|
||||
|
||||
|
||||
// Internal state used by the unifier
|
||||
ByteString CurrentFieldName;
|
||||
|
@ -1400,15 +1420,15 @@ namespace bolt {
|
|||
TypePath RightPath;
|
||||
|
||||
Type* getLeft() const {
|
||||
return Constraint->Left;
|
||||
return Left;
|
||||
}
|
||||
|
||||
Type* getRight() const {
|
||||
return Constraint->Right;
|
||||
return Right;
|
||||
}
|
||||
|
||||
Node* getSource() const {
|
||||
return Constraint->Source;
|
||||
return Source;
|
||||
}
|
||||
|
||||
bool unifyField(Type* A, Type* B, bool DidSwap);
|
||||
|
@ -1416,7 +1436,7 @@ namespace bolt {
|
|||
bool unify(Type* A, Type* B, bool DidSwap);
|
||||
|
||||
bool unify() {
|
||||
return unify(Constraint->Left, Constraint->Right, false);
|
||||
return unify(Left, Right, false);
|
||||
}
|
||||
|
||||
std::vector<TypeclassContext> findInstanceContext(const TypeSig& Ty, TypeclassId& Class) {
|
||||
|
@ -1548,16 +1568,16 @@ namespace bolt {
|
|||
|
||||
bool Unifier::unify(Type* A, Type* B, bool DidSwap) {
|
||||
|
||||
A = C.simplifyType(A);
|
||||
B = C.simplifyType(B);
|
||||
A = A->find();
|
||||
B = B->find();
|
||||
|
||||
auto unifyError = [&]() {
|
||||
C.DE.add<UnificationErrorDiagnostic>(
|
||||
Constraint->Left,
|
||||
Constraint->Right,
|
||||
Left,
|
||||
Right,
|
||||
LeftPath,
|
||||
RightPath,
|
||||
Constraint->Source
|
||||
Source
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1717,12 +1737,12 @@ namespace bolt {
|
|||
return Success;
|
||||
}
|
||||
|
||||
if (A->isTupleIndex() || B->isTupleIndex()) {
|
||||
// Type(s) could not be simplified at the beginning of this function,
|
||||
// so we have to re-visit the constraint when there is more information.
|
||||
C.Queue.push_back(Constraint);
|
||||
return true;
|
||||
}
|
||||
// if (A->isTupleIndex() || B->isTupleIndex()) {
|
||||
// // Type(s) could not be simplified at the beginning of this function,
|
||||
// // so we have to re-visit the constraint when there is more information.
|
||||
// C.Queue.push_back(Constraint);
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// This does not work because it ignores the indices
|
||||
// if (A->isTupleIndex() && B->isTupleIndex()) {
|
||||
|
@ -1806,9 +1826,9 @@ namespace bolt {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Checker::solveEqual(CEqual* C) {
|
||||
void Checker::unify(Type* Left, Type* Right, Node* Source) {
|
||||
// std::cerr << describe(C->Left) << " ~ " << describe(C->Right) << std::endl;
|
||||
Unifier A { *this, C };
|
||||
Unifier A { *this, Left, Right, Source };
|
||||
A.unify();
|
||||
}
|
||||
|
||||
|
|
|
@ -235,11 +235,6 @@ namespace bolt {
|
|||
Out << ")";
|
||||
return Out.str();
|
||||
}
|
||||
case TypeKind::TupleIndex:
|
||||
{
|
||||
auto Y = Ty->asTupleIndex();
|
||||
return describe(Y.Ty) + "." + std::to_string(Y.I);
|
||||
}
|
||||
case TypeKind::Nil:
|
||||
return "{}";
|
||||
case TypeKind::Absent:
|
||||
|
@ -617,14 +612,6 @@ namespace bolt {
|
|||
W.write(")");
|
||||
}
|
||||
|
||||
void visitTupleIndexType(const TTupleIndex& Ty) override {
|
||||
Path.push_back(TypeIndex::forTupleIndexType());
|
||||
visit(Ty.Ty);
|
||||
Path.pop_back();
|
||||
W.write(".");
|
||||
W.write(Ty.I);
|
||||
}
|
||||
|
||||
void visitNilType(const TNil& Ty) override {
|
||||
W.write("{}");
|
||||
}
|
||||
|
@ -889,6 +876,9 @@ namespace bolt {
|
|||
writeType(E.I);
|
||||
write(" is out of range for tuple ");
|
||||
writeType(E.Tuple);
|
||||
write("\n\n");
|
||||
writeNode(E.Source);
|
||||
write("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -927,7 +917,9 @@ namespace bolt {
|
|||
writePrefix(E);
|
||||
write("the type ");
|
||||
writeType(E.Ty);
|
||||
write(" is not a tuple.\n");
|
||||
write(" is not a tuple.\n\n");
|
||||
writeNode(E.Source);
|
||||
write("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <sys/wait.h>
|
||||
#include <vector>
|
||||
|
||||
#include "zen/range.hpp"
|
||||
|
||||
namespace bolt {
|
||||
|
||||
bool TypeclassSignature::operator<(const TypeclassSignature& Other) const {
|
||||
|
@ -60,10 +62,6 @@ namespace bolt {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TTupleIndex::operator==(const TTupleIndex& Other) const {
|
||||
return *Ty == *Other.Ty && I == Other.I;
|
||||
}
|
||||
|
||||
bool TNil::operator==(const TNil& Other) const {
|
||||
return true;
|
||||
}
|
||||
|
@ -101,8 +99,6 @@ namespace bolt {
|
|||
return Nil == Other.Nil;
|
||||
case TypeKind::Tuple:
|
||||
return Tuple == Other.Tuple;
|
||||
case TypeKind::TupleIndex:
|
||||
return TupleIndex == Other.TupleIndex;
|
||||
case TypeKind::App:
|
||||
return App == Other.App;
|
||||
}
|
||||
|
@ -145,11 +141,6 @@ namespace bolt {
|
|||
Proc(Present.Ty);
|
||||
break;
|
||||
}
|
||||
case TypeKind::TupleIndex:
|
||||
{
|
||||
Proc(TupleIndex.Ty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,12 +181,6 @@ namespace bolt {
|
|||
}
|
||||
return new Type(TApp(NewOp, NewArg));
|
||||
}
|
||||
case TypeKind::TupleIndex:
|
||||
{
|
||||
auto Tuple = Ty2->asTupleIndex();
|
||||
auto NewTy = Tuple.Ty->rewrite(Fn, Recursive);
|
||||
return NewTy != Tuple.Ty ? new Type(TTupleIndex(NewTy, Tuple.I)) : Ty2;
|
||||
}
|
||||
case TypeKind::Tuple:
|
||||
{
|
||||
auto Tuple = Ty2->asTuple();
|
||||
|
@ -258,8 +243,6 @@ namespace bolt {
|
|||
return this->asApp().Op;
|
||||
case TypeIndexKind::AppArgType:
|
||||
return this->asApp().Arg;
|
||||
case TypeIndexKind::TupleIndexType:
|
||||
return this->asTupleIndex().Ty;
|
||||
case TypeIndexKind::TupleElement:
|
||||
return this->asTuple().ElementTypes[Index.I];
|
||||
case TypeIndexKind::ArrowParamType:
|
||||
|
@ -336,8 +319,6 @@ namespace bolt {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
case TypeKind::TupleIndex:
|
||||
return TupleIndex.Ty->hasTypeVar(TV);
|
||||
case TypeKind::Field:
|
||||
return Field.Ty->hasTypeVar(TV) || Field.RestTy->hasTypeVar(TV);
|
||||
case TypeKind::Arrow:
|
||||
|
|
Loading…
Reference in a new issue