diff options
Diffstat (limited to 'src/test/java')
| -rw-r--r-- | src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java index d758cd96..af4d46e4 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerIsSubTypeTests.java @@ -133,7 +133,7 @@ public class TypeCheckerIsSubTypeTests { Sources.NULL, TypeCheckerSubTyping.constraints(List.of(typeParam), TypeInfos.EMPTY) ); - var result = constraints.solve(); + var result = constraints.solve(Sources.NULL); assertThat(result, equalTo(TypeSubstitutionMap.of( Map.entry(typeParam, Types.INT) @@ -305,6 +305,130 @@ public class TypeCheckerIsSubTypeTests { assertThat(isSubType(constructedSumType, variantType2, typeInfos), equalTo(false)); } + @Test + public void constraintsFromSumSupertypeAreRetained() { + var namespaceName = NamespaceName.of("Example", "Project"); + var sumType = Types.sum(namespaceName, "Sum"); + var variantType1 = Types.struct(namespaceName, "Variant1"); + var variantType2 = Types.struct(namespaceName, "Variant2"); + var variantTypeConstructor2 = Types.typeConstructor( + List.of(TypeParam.forStructType(variantType2, "T")), + variantType2 + ); + var typeInfos = TypeInfos.EMPTY + .addSumTypeInfo(sumType, new SumTypeInfo(P.orderedSet( + variantType1, + Types.constructedStructType( + variantTypeConstructor2, + List.of(TypeParam.forSumType(sumType, "T")) + ) + ))); + + var constraints = TypeCheckerSubTyping.constraints( + List.of(TypeParam.forSumType(sumType, "T")), + typeInfos + ); + constraints = TypeCheckerSubTyping.addSubtypeConstraint( + Types.constructedStructType( + variantTypeConstructor2, + List.of(Types.STRING) + ), + sumType, + Sources.NULL, + constraints + ); + var result = constraints.solve(Sources.NULL); + + assertThat(result, equalTo(TypeSubstitutionMap.of( + Map.entry(TypeParam.forSumType(sumType, "T"), Types.STRING) + ))); + } + + // == Constructed types == + + @Test + public void constructedTypeCanBeSubtypeOfConstructedTypeWithBoundTypeParam() { + var namespaceName = NamespaceName.of("Example", "Project"); + var sumType = Types.sum(namespaceName, "Sum"); + var structType = Types.struct(namespaceName, "Struct"); + var typeConstructor = Types.typeConstructor( + List.of(TypeParam.forStructType(structType, "T")), + structType + ); + var typeInfos = TypeInfos.EMPTY; + + var constraints = TypeCheckerSubTyping.constraints( + List.of(TypeParam.forSumType(sumType, "T")), + typeInfos + ); + constraints = TypeCheckerSubTyping.addSubtypeConstraint( + Types.constructedStructType( + typeConstructor, + List.of(Types.STRING) + ), + Types.constructedStructType( + typeConstructor, + List.of(TypeParam.forSumType(sumType, "T")) + ), + Sources.NULL, + constraints + ); + var result = constraints.solve(Sources.NULL); + + assertThat(result, equalTo(TypeSubstitutionMap.of( + Map.entry(TypeParam.forSumType(sumType, "T"), Types.STRING) + ))); + } + + @Test + public void constructedTypesWithDifferentArgsCannotBothBeSubtypesOfConstructedTypeWithInvariantTypeParam() { + var namespaceName = NamespaceName.of("Example", "Project"); + var sumType = Types.sum(namespaceName, "Sum"); + var structType = Types.struct(namespaceName, "Struct"); + var typeConstructor = Types.typeConstructor( + List.of(TypeParam.forStructType(structType, "T")), + structType + ); + var typeInfos = TypeInfos.EMPTY; + + var constraints = TypeCheckerSubTyping.constraints( + List.of(TypeParam.forSumType(sumType, "T")), + typeInfos + ); + constraints = TypeCheckerSubTyping.addSubtypeConstraint( + Types.constructedStructType( + typeConstructor, + List.of(Types.STRING) + ), + Types.constructedStructType( + typeConstructor, + List.of(TypeParam.forSumType(sumType, "T")) + ), + Sources.NULL, + constraints + ); + constraints = TypeCheckerSubTyping.addSubtypeConstraint( + Types.constructedStructType( + typeConstructor, + List.of(Types.INT) + ), + Types.constructedStructType( + typeConstructor, + List.of(TypeParam.forSumType(sumType, "T")) + ), + Sources.NULL, + constraints + ); + var c = constraints; + var error = assertThrows( + // TODO: more specific error + IllegalStateException.class, + () -> c.solve(Sources.NULL) + ); + + assertThat(error.getMessage(), equalTo("Incompatible type bounds")); + } + // == Function types == @Test |
