summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-check-type.cpp')
-rw-r--r--source/slang/slang-check-type.cpp37
1 files changed, 33 insertions, 4 deletions
diff --git a/source/slang/slang-check-type.cpp b/source/slang/slang-check-type.cpp
index d5d3e5a5d..5967da8b0 100644
--- a/source/slang/slang-check-type.cpp
+++ b/source/slang/slang-check-type.cpp
@@ -273,7 +273,8 @@ namespace Slang
auto genericDeclRef = genericDeclRefType->getDeclRef();
ensureDecl(genericDeclRef, DeclCheckState::CanSpecializeGeneric);
- List<Expr*> args;
+ List<Val*> args;
+ List<Val*> witnessArgs;
for (Decl* member : genericDeclRef.getDecl()->members)
{
if (auto typeParam = as<GenericTypeParamDecl>(member))
@@ -290,7 +291,7 @@ namespace Slang
// TODO: this is one place where syntax should get cloned!
if (outProperType)
- args.add(typeParam->initType.exp);
+ args.add(ExtractGenericArgVal(typeParam->initType.exp));
}
else if (auto valParam = as<GenericValueParamDecl>(member))
{
@@ -305,14 +306,42 @@ namespace Slang
}
// TODO: this is one place where syntax should get cloned!
if (outProperType)
- args.add(valParam->initExpr);
+ args.add(ExtractGenericArgVal(valParam->initExpr));
+ }
+ else if (auto constraintParam = as<GenericTypeConstraintDecl>(member))
+ {
+ auto genericParam = as<DeclRefType>(constraintParam->sub.type)->getDeclRef();
+ if (!genericParam)
+ return false;
+ auto genericTypeParamDecl = as<GenericTypeParamDecl>(genericParam.getDecl());
+ if (!genericTypeParamDecl)
+ return false;
+ auto defaultType = CheckProperType(genericTypeParamDecl->initType);
+ auto witness = tryGetSubtypeWitness(defaultType, CheckProperType(constraintParam->sup));
+ if (!witness)
+ {
+ // diagnose
+ getSink()->diagnose(
+ genericTypeParamDecl->initType.exp,
+ Diagnostics::typeArgumentDoesNotConformToInterface,
+ defaultType,
+ constraintParam->sup);
+
+ SLANG_UNEXPECTED("default type argument does not conform to interface");
+ return false;
+ }
+ witnessArgs.add(witness);
}
else
{
// ignore non-parameter members
}
}
- result = InstantiateGenericType(genericDeclRef, args);
+ // Combine args and witnessArgs
+ args.addRange(witnessArgs);
+
+ result = DeclRefType::create(getASTBuilder(),
+ getASTBuilder()->getGenericAppDeclRef(genericDeclRef, args.getArrayView()));
}
// default case: we expect this to already be a proper type