From bbc57bddb4dea75e3774673dbb173662e930c3dc Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 29 Dec 2023 11:22:55 +0000 Subject: Support subtyping for constructed sum types --- .../compiler/typechecker/TypeCheckerContext.java | 25 ++++++++++++++++++++++ .../compiler/typechecker/TypeCheckerSubTyping.java | 10 +++++++++ 2 files changed, 35 insertions(+) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java index dcaa9226..ffd2ac01 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerContext.java @@ -481,6 +481,31 @@ public class TypeCheckerContext { .orElseThrow(() -> new MissingSumTypeInfoError(type, source)); } + public SumTypeInfo sumTypeInfo(ConstructedType type, Source source) { + var typeInfo = sumTypeInfo(type.genericType(), source); + + var typeSubstitutionMap = type.typeSubstitutionMap(); + + var variants = typeInfo.variants().stream() + .map(variant -> switch (variant) { + case SumVariant.ConstructedStruct constructedStruct -> + // TODO: overload to avoid cast? + SumVariant.constructedStruct((ConstructedType) TypeSubstitution.substitute( + constructedStruct.type(), + typeSubstitutionMap + )); + + case SumVariant.Struct struct -> + SumVariant.struct((StructType) TypeSubstitution.substitute( + struct.type(), + typeSubstitutionMap + )); + }) + .collect(PCollectors.toOrderedSet()); + + return new SumTypeInfo(variants); + } + public TypeCheckerContext addUserDefinedEffectInfo( UserDefinedEffect effect, UserDefinedEffectInfo effectInfo diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java index 2c69ac14..4aab5370 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java @@ -28,6 +28,16 @@ public class TypeCheckerSubTyping { .anyMatch(supertypeVariant -> isSubType(subtype, supertypeVariant.toType(), context)); } + if ( + supertype instanceof ConstructedType supertypeConstructedType && + supertypeConstructedType.genericType() instanceof SumType + ) { + // TODO: merge with logic for plain sum types + var superTypeInfo = context.sumTypeInfo((ConstructedType) supertypeConstructedType, Sources.NULL); + return superTypeInfo.variants().stream() + .anyMatch(supertypeVariant -> isSubType(subtype, supertypeVariant.toType(), context)); + } + if ( supertype instanceof FunctionType supertypeFunction && subtype instanceof FunctionType subtypeFunction -- cgit v1.2.3