summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java7
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java22
3 files changed, 37 insertions, 2 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
index 9429313..eb47870 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -393,8 +393,14 @@ public class TypeChecker {
TypeCheckerNamespaceContext context
) {
var typedReceiver = typeCheckTypeLevelExpression(untyped.receiver(), context);
- // TODO: check this properly
- var receiver = (TypeConstructor<?>) typedReceiver.value();
+
+ if (!(typedReceiver.value() instanceof TypeConstructor<?> receiver)) {
+ throw new UnexpectedTypeError(
+ new TypeSet.TypeConstructor(),
+ new TypeLevelValueType(typedReceiver.value()),
+ untyped.receiver().source()
+ );
+ }
if (untyped.args().size() != receiver.params().size()) {
throw new WrongNumberOfTypeLevelArgsError(
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java
index f587897..c3896d9 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeSet.java
@@ -16,4 +16,11 @@ public sealed interface TypeSet {
return "metatype";
}
}
+
+ record TypeConstructor() implements TypeSet {
+ @Override
+ public String describe() {
+ return "type constructor";
+ }
+ }
}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java
index c0a7f93..4f409d2 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java
@@ -3,6 +3,7 @@ package org.zwobble.hobgoblin.compiler.typechecker;
import org.junit.jupiter.api.Test;
import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedArb;
import org.zwobble.hobgoblin.compiler.sources.NullSource;
+import org.zwobble.hobgoblin.compiler.typechecker.errors.UnexpectedTypeError;
import org.zwobble.hobgoblin.compiler.typechecker.errors.WrongNumberOfTypeLevelArgsError;
import org.zwobble.hobgoblin.compiler.types.*;
@@ -15,6 +16,27 @@ import static org.zwobble.precisely.Matchers.equalTo;
public class TypeCheckerConstructedTypeTests {
@Test
+ public void whenReceiverIsNotTypeConstructorThenErrorIsThrown() {
+ var untyped = UntypedArb.constructedType(
+ UntypedArb.typeLevelReference("List"),
+ List.of(UntypedArb.typeLevelReference("Int32"))
+ );
+ var context = TypeCheckerContextArb.namespaceContext();
+ var listType = SimpleNativeType.builtin("List");
+ context.declare("List", new TypeLevelValueType(listType), NullSource.INSTANCE);
+ var int32Type = SimpleNativeType.builtin("Int32");
+ context.declare("Int32", new TypeLevelValueType(int32Type), NullSource.INSTANCE);
+
+ var error = assertThrows(
+ UnexpectedTypeError.class,
+ () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context)
+ );
+
+ assertThat(error.expected(), equalTo(new TypeSet.TypeConstructor()));
+ assertThat(error.actual(), equalTo(new TypeLevelValueType(listType)));
+ }
+
+ @Test
public void whenArgsMatchParamsThenCanConstructTypeFromTypeConstructor() {
var untyped = UntypedArb.constructedType(
UntypedArb.typeLevelReference("List"),