summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorYONGH\yongh <yonghe@outlook.com>2017-11-02 19:21:15 -0400
committerYONGH\yongh <yonghe@outlook.com>2017-11-02 19:21:15 -0400
commitd5e2319c33115d0241dd9d2047c0a5f029553dde (patch)
treeb89aef27f2330e7c568b0f799f0902015fdd4f18 /source
parente2b97607977977fd2dbe298c2bb4512f4715dd4c (diff)
work inprogress
Diffstat (limited to 'source')
-rw-r--r--source/slang/check.cpp53
-rw-r--r--source/slang/lookup.cpp21
-rw-r--r--source/slang/parser.cpp25
-rw-r--r--source/slang/syntax.cpp36
4 files changed, 81 insertions, 54 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 2f4ed2ce8..dc4e48545 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -169,23 +169,18 @@ namespace Slang
sexpr->declRef = declRef;
expr = sexpr;
}
- if (auto assocTypeDeclRef = declRef.As<AssocTypeDecl>())
+ if (auto constraintType = expr->type->As<GenericConstraintDeclRefType>())
{
- if (auto genConstraintType = baseExpr->type->As<GenericConstraintDeclRefType>())
- {
- // if this is a reference from a generic parameter, we need to generate a AssocTypeDeclRefType type.
- // for example, if we have an expression T.U where T:ISimple, and U is an associated type defined in ISimple.
- // then this expression should evaluate to AssocTypeDeclRefType(T, U).
- auto assocTypeDeclType = new AssocTypeDeclRefType();
- assocTypeDeclType->declRef = assocTypeDeclRef;
- assocTypeDeclType->sourceType = genConstraintType->subType;
- assocTypeDeclType->setSession(getSession());
- expr->type = QualType(getTypeType(assocTypeDeclType));
- }
+ if (baseExpr->type->As<TypeType>())
+ constraintType->subType = baseExpr->type->As<TypeType>()->type;
+ else
+ constraintType->subType = baseExpr->type;
+
}
- else if (auto funcDeclRef = declRef.As<CallableDecl>())
+
+ if (auto genConstraintType = baseExpr->type->As<GenericConstraintDeclRefType>())
{
- if (auto genConstraintType = baseExpr->type->As<GenericConstraintDeclRefType>())
+ if (auto funcDeclRef = declRef.As<CallableDecl>())
{
// if this is call expression, propagate the source associated type to the result type
auto funcType = expr->type->As<FuncType>();
@@ -201,9 +196,24 @@ namespace Slang
newFuncType->setSession(funcType->getSession());
expr->type = QualType(newFuncType);
}
-
+ }
+ else if (auto assocTypeDeclRef = declRef.As<AssocTypeDecl>())
+ {
+ auto assocTypeDeclType = new AssocTypeDeclRefType();
+ assocTypeDeclType->declRef = assocTypeDeclRef;
+ assocTypeDeclType->sourceType = genConstraintType->subType;
+ assocTypeDeclType->setSession(getSession());
+ expr->type = QualType(getTypeType(assocTypeDeclType));
}
}
+ else if (auto assocTypeDeclRef = declRef.As<AssocTypeDecl>())
+ {
+ auto assocTypeDeclType = new AssocTypeDeclRefType();
+ assocTypeDeclType->declRef = assocTypeDeclRef;
+ assocTypeDeclType->sourceType = baseExpr->type;
+ assocTypeDeclType->setSession(getSession());
+ expr->type = QualType(getTypeType(assocTypeDeclType));
+ }
return expr;
}
else
@@ -1262,6 +1272,14 @@ namespace Slang
checkDecl(genericDecl->inner);
}
+ void visitGenericTypeConstraintDecl(GenericTypeConstraintDecl * genericConstraintDecl)
+ {
+ // check the type being inherited from
+ auto base = genericConstraintDecl->sup;
+ base = TranslateTypeNode(base);
+ genericConstraintDecl->sup = base;
+ }
+
void visitInheritanceDecl(InheritanceDecl* inheritanceDecl)
{
// check the type being inherited from
@@ -1325,11 +1343,6 @@ namespace Slang
// These are only used in the stdlib, so no checking is needed for now
}
- void visitGenericTypeConstraintDecl(GenericTypeConstraintDecl*)
- {
- // These are only used in the stdlib, so no checking is needed for now
- }
-
void visitModifier(Modifier*)
{
// Do nothing with modifiers for now
diff --git a/source/slang/lookup.cpp b/source/slang/lookup.cpp
index c0cb657c4..b97dac560 100644
--- a/source/slang/lookup.cpp
+++ b/source/slang/lookup.cpp
@@ -453,6 +453,27 @@ void lookUpMemberImpl(
}
}
}
+ else if (auto assocTypeDeclRefType = type->As<AssocTypeDeclRefType>())
+ {
+ auto assocTypeDeclRef = assocTypeDeclRefType->declRef;
+ for (auto constraintDeclRef : getMembersOfType<GenericTypeConstraintDecl>(assocTypeDeclRef))
+ {
+ // The super-type in the constraint (e.g., `Foo` in `T : Foo`)
+ // will tell us a type we should use for lookup.
+ auto bound = GetSup(constraintDeclRef);
+
+ // Go ahead and use the target type, with an appropriate breadcrumb
+ // to indicate that we indirected through a type constraint.
+
+ BreadcrumbInfo breadcrumb;
+ breadcrumb.prev = inBreadcrumbs;
+ breadcrumb.kind = LookupResultItem::Breadcrumb::Kind::Constraint;
+ breadcrumb.declRef = constraintDeclRef;
+
+ // TODO: Need to consider case where this might recurse infinitely.
+ lookUpMemberImpl(session, semantics, name, bound, ioResult, &breadcrumb);
+ }
+ }
}
LookupResult lookUpMember(
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 224450a66..bf85356db 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -2113,7 +2113,30 @@ namespace Slang
auto nameToken = parser->ReadToken(TokenType::Identifier);
assocTypeDecl->nameAndLoc = NameLoc(nameToken);
assocTypeDecl->loc = nameToken.loc;
- parseOptionalInheritanceClause(parser, assocTypeDecl.Ptr());
+ if (AdvanceIf(parser, TokenType::Colon))
+ {
+ while (!parser->tokenReader.IsAtEnd())
+ {
+ auto paramConstraint = new GenericTypeConstraintDecl();
+ parser->FillPosition(paramConstraint);
+
+ auto paramType = DeclRefType::Create(
+ parser->getSession(),
+ DeclRef<Decl>(assocTypeDecl, nullptr));
+
+ auto paramTypeExpr = new SharedTypeExpr();
+ paramTypeExpr->loc = assocTypeDecl->loc;
+ paramTypeExpr->base.type = paramType;
+ paramTypeExpr->type = QualType(getTypeType(paramType));
+
+ paramConstraint->sub = TypeExp(paramTypeExpr);
+ paramConstraint->sup = parser->ParseTypeExp();
+
+ AddMember(assocTypeDecl, paramConstraint);
+ if (!AdvanceIf(parser, TokenType::Comma))
+ break;
+ }
+ }
parser->ReadToken(TokenType::Semicolon);
return assocTypeDecl;
}
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index fd7fc0e14..3e38955ba 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -961,7 +961,8 @@ void Type::accept(IValVisitor* visitor, void* extra)
{
if (!sourceType)
return this;
- if (auto parentDeclRefType = sourceType->As<DeclRefType>())
+ auto substSourceType = sourceType->SubstituteImpl(subst, ioDiff);
+ if (auto parentDeclRefType = substSourceType.As<DeclRefType>())
{
auto parentDeclRef = parentDeclRefType->declRef;
DeclRef<AggTypeDecl> newParentDeclRef = parentDeclRef.As<AggTypeDecl>();
@@ -1045,38 +1046,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
RefPtr<Val> GenericConstraintDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff)
{
- auto genParamDecl = subType.As<DeclRefType>()->declRef.As<GenericTypeParamDecl>();
- // search for a substitution that might apply to us
- for (auto s = subst; s; s = s->outer.Ptr())
- {
- // the generic decl associated with the substitution list must be
- // the generic decl that declared this parameter
- auto genericDecl = s->genericDecl;
- if (genericDecl != genParamDecl.getDecl()->ParentDecl)
- continue;
- int index = 0;
- for (auto m : genericDecl->Members)
- {
- if (m.Ptr() == genParamDecl.getDecl())
- {
- // We've found it, so return the corresponding specialization argument
- (*ioDiff)++;
- return s->args[index];
- }
- else if (auto typeParam = m.As<GenericTypeParamDecl>())
- {
- index++;
- }
- else if (auto valParam = m.As<GenericValueParamDecl>())
- {
- index++;
- }
- else
- {
- }
- }
- }
- return this;
+ return subType->SubstituteImpl(subst, ioDiff);
}
int GenericConstraintDeclRefType::GetHashCode()