aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-29 11:22:55 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-29 11:22:55 +0000
commitbbc57bddb4dea75e3774673dbb173662e930c3dc (patch)
treec21931d110e5719249888efbc1fa721b030f777e /src/test/java/org
parent1fef4fd33b335d78bc91a174b970be05bf8a5b39 (diff)
Support subtyping for constructed sum types
Diffstat (limited to 'src/test/java/org')
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java
index 568256c2..ca3008f3 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java
@@ -4,6 +4,8 @@ import org.junit.jupiter.api.Test;
import org.shedlang.compiler.types.*;
import org.shedlang.compiler.util.P;
+import java.util.List;
+
import static org.shedlang.compiler.typechecker.TypeCheckerSubTyping.isSubType;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.equalTo;
@@ -138,6 +140,93 @@ public class TypeCheckerIsSubTypeTests {
}
@Test
+ public void variantWithoutTypeLevelArgIsSubTypeOfConstructedSumType() {
+ var namespaceName = NamespaceName.of("Example", "Project");
+ var sumType = Types.sum(namespaceName, "Sum");
+ var sumTypeConstructor = Types.typeConstructor(
+ List.of(TypeParam.forSumType(sumType, "T")),
+ sumType
+ );
+ var constructedSumType = Types.constructedType(
+ sumTypeConstructor,
+ List.of(Types.STRING)
+ );
+ var variantType1 = Types.struct(namespaceName, "Variant1");
+ var variantType2 = Types.struct(namespaceName, "Variant2");
+ var context = TypeCheckerContext.EMPTY
+ .addSumTypeInfo(sumType, new SumTypeInfo(P.orderedSet(
+ SumVariant.struct(variantType1),
+ SumVariant.struct(variantType2)
+ )));
+
+ assertThat(isSubType(variantType1, constructedSumType, context), equalTo(true));
+ assertThat(isSubType(variantType2, constructedSumType, context), equalTo(true));
+ }
+
+ @Test
+ public void variantWithTypeLevelArgIsSubTypeOfConstructedSumType() {
+ var namespaceName = NamespaceName.of("Example", "Project");
+ var sumType = Types.sum(namespaceName, "Sum");
+ var sumTypeConstructor = Types.typeConstructor(
+ List.of(TypeParam.forSumType(sumType, "T")),
+ sumType
+ );
+ var constructedSumType = Types.constructedType(
+ sumTypeConstructor,
+ List.of(Types.STRING)
+ );
+ var variantType1 = Types.struct(namespaceName, "Variant1");
+ var variantTypeConstructor1 = Types.typeConstructor(
+ List.of(TypeParam.forStructType(variantType1, "T")),
+ variantType1
+ );
+ var constructedVariantType1 = Types.constructedType(
+ variantTypeConstructor1,
+ List.of(Types.STRING)
+ );
+ var variantType2 = Types.struct(namespaceName, "Variant2");
+ var context = TypeCheckerContext.EMPTY
+ .addSumTypeInfo(sumType, new SumTypeInfo(P.orderedSet(
+ SumVariant.constructedStruct(constructedVariantType1),
+ SumVariant.struct(variantType2)
+ )));
+
+ assertThat(isSubType(constructedVariantType1, constructedSumType, context), equalTo(true));
+ assertThat(
+ isSubType(
+ Types.constructedType(variantTypeConstructor1, List.of(Types.INT)),
+ constructedSumType,
+ context
+ ),
+ equalTo(false)
+ );
+ }
+
+ @Test
+ public void variantIsNotSuperTypeOfConstructedSumType() {
+ var namespaceName = NamespaceName.of("Example", "Project");
+ var sumType = Types.sum(namespaceName, "Sum");
+ var sumTypeConstructor = Types.typeConstructor(
+ List.of(TypeParam.forSumType(sumType, "T")),
+ sumType
+ );
+ var constructedSumType = Types.constructedType(
+ sumTypeConstructor,
+ List.of(Types.STRING)
+ );
+ var variantType1 = Types.struct(namespaceName, "Variant1");
+ var variantType2 = Types.struct(namespaceName, "Variant2");
+ var context = TypeCheckerContext.EMPTY
+ .addSumTypeInfo(sumType, new SumTypeInfo(P.orderedSet(
+ SumVariant.struct(variantType1),
+ SumVariant.struct(variantType2)
+ )));
+
+ assertThat(isSubType(constructedSumType, variantType1, context), equalTo(false));
+ assertThat(isSubType(constructedSumType, variantType2, context), equalTo(false));
+ }
+
+ @Test
public void whenFunctionsHaveDifferentPositionalParamCountsThenTheyAreNotSubtypes() {
var functionType1 = FunctionType.builder()
.addPositionalParam(Types.STRING)