From ff49a4cd2231787867b4aafc95bd5705057bfcc3 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 2 Aug 2026 14:19:23 +0100 Subject: Introduce NativeTypeConstructor for greater safety --- .../hobgoblin/compiler/builtins/NativeTypes.java | 8 ++++---- .../hobgoblin/compiler/typechecker/TypeChecker.java | 9 +++------ .../compiler/types/NativeTypeConstructor.java | 9 +++++++++ .../hobgoblin/compiler/types/TypeConstructor.java | 13 ++++++------- .../org/zwobble/hobgoblin/compiler/types/Types.java | 18 ++++++++++++++++++ 5 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/types/NativeTypeConstructor.java create mode 100644 src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java (limited to 'src/main/java/org/zwobble') diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/builtins/NativeTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/builtins/NativeTypes.java index 485df8c..f4e499e 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/builtins/NativeTypes.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/builtins/NativeTypes.java @@ -13,7 +13,7 @@ public class NativeTypes { public static final SimpleNativeType BOX_INNER = SimpleNativeType.builtin("Box"); - public static TypeConstructor BOX = new TypeConstructor<>( + public static TypeConstructor BOX = Types.constructor( List.of(new TypeParam("T")), BOX_INNER ); @@ -24,7 +24,7 @@ public class NativeTypes { public static final SimpleNativeType LIST_INNER = SimpleNativeType.builtin("List"); - public static TypeConstructor LIST = new TypeConstructor<>( + public static TypeConstructor LIST = Types.constructor( List.of(new TypeParam("T")), LIST_INNER ); @@ -35,7 +35,7 @@ public class NativeTypes { public static final SimpleNativeType OPTION_INNER = SimpleNativeType.builtin("Option"); - public static TypeConstructor OPTION = new TypeConstructor<>( + public static TypeConstructor OPTION = Types.constructor( List.of(new TypeParam("T")), OPTION_INNER ); @@ -46,7 +46,7 @@ public class NativeTypes { public static final SimpleNativeType SHARED_INNER = SimpleNativeType.builtin("Shared"); - public static TypeConstructor SHARED = new TypeConstructor<>( + public static TypeConstructor SHARED = Types.constructor( List.of(new TypeParam("T")), SHARED_INNER ); 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 4b02f60..9429313 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -408,12 +408,9 @@ public class TypeChecker { .map(untypedArg -> typeCheckMetaType(untypedArg, context).value()) .toList(); - var constructedType = switch (receiver.genericType()) { - case SimpleNativeType _ -> { - @SuppressWarnings("unchecked") - var narrowReceiver = (TypeConstructor) receiver; - yield new ConstructedNativeType(narrowReceiver, args); - } + var constructedType = switch (receiver) { + case NativeTypeConstructor nativeTypeConstructor -> + new ConstructedNativeType(nativeTypeConstructor, args); }; return new TypedConstructedTypeNode( diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/NativeTypeConstructor.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/NativeTypeConstructor.java new file mode 100644 index 0000000..43e0cfc --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/NativeTypeConstructor.java @@ -0,0 +1,9 @@ +package org.zwobble.hobgoblin.compiler.types; + +import java.util.List; + +public record NativeTypeConstructor( + List params, + SimpleNativeType genericType +) implements TypeConstructor { +} diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java index 1e412d7..e2726fb 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TypeConstructor.java @@ -2,12 +2,11 @@ package org.zwobble.hobgoblin.compiler.types; import java.util.List; -public record TypeConstructor( - List params, - T genericType -) implements TypeLevelValue { - @Override - public String describe() { - return genericType.describe(); +public sealed interface TypeConstructor extends TypeLevelValue permits NativeTypeConstructor { + List params(); + T genericType(); + + default String describe() { + return genericType().describe(); } } diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java new file mode 100644 index 0000000..6d8fcbb --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Types.java @@ -0,0 +1,18 @@ +package org.zwobble.hobgoblin.compiler.types; + +import java.util.List; + +public class Types { + private Types() {} + + @SuppressWarnings("unchecked") + public static TypeConstructor constructor( + List params, + T genericType + ) { + return (TypeConstructor) switch (genericType) { + case SimpleNativeType simpleNativeType -> + new NativeTypeConstructor(params, simpleNativeType); + }; + } +} -- cgit v1.2.3