diff options
| author | Michael Williamson <mike@zwobble.org> | 2024-03-02 14:16:28 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2024-03-02 14:16:28 +0000 |
| commit | daf4e4df6d06a2ec498e266f83cc9441c8075387 (patch) | |
| tree | 4488e0ad3c45764e9380e3fc3fb1ffe7d8e1a910 /src/main/java | |
| parent | c42ba95025b19c7eb51a1435881b46cfcb384de6 (diff) | |
Extract inferTypeArgType()
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java index 5ff13d5b..90f3db71 100644 --- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java +++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java @@ -83,32 +83,7 @@ public class TypeCheckerSubTyping { var map = this.typeBounds.keySet().stream() .map(typeArg -> { - var typeParamBounds = this.typeBounds.getOrDefault(typeArg, TypeBounds.EMPTY); - - var lowerBound = Types.BOTTOM; - for (var lower : typeParamBounds.lower) { - lowerBound = Types.commonSupertype( - List.of(lowerBound, lower), - this.typeInfos - ); - } - - var upperBound = Types.TOP; - for (var upper : typeParamBounds.upper) { - upperBound = Types.commonSubtype( - List.of(upperBound, upper), - this.typeInfos - ); - } - - if (!isSubType(lowerBound, upperBound, typeInfos)) { - // TODO: proper error (or return empty and let caller throw?) - throw new IllegalStateException("Incompatible type bounds"); - } - - var inferredType = typeParamBounds.lower.isEmpty() && !typeParamBounds.upper.isEmpty() - ? upperBound - : lowerBound; + var inferredType = inferTypeArgType(typeArg); return Map.<TypeLevelParam, TypeLevelValue>entry(typeArg.param(), inferredType); }) @@ -116,6 +91,36 @@ public class TypeCheckerSubTyping { return new TypeSubstitutionMap(map); } + + private Type inferTypeArgType(TypeArg typeArg) { + var typeParamBounds = this.typeBounds.getOrDefault(typeArg, TypeBounds.EMPTY); + + var lowerBound = Types.BOTTOM; + for (var lower : typeParamBounds.lower) { + lowerBound = Types.commonSupertype( + List.of(lowerBound, lower), + this.typeInfos + ); + } + + var upperBound = Types.TOP; + for (var upper : typeParamBounds.upper) { + upperBound = Types.commonSubtype( + List.of(upperBound, upper), + this.typeInfos + ); + } + + if (!isSubType(lowerBound, upperBound, typeInfos)) { + // TODO: proper error (or return empty and let caller throw?) + throw new IllegalStateException("Incompatible type bounds"); + } + + var inferredType = typeParamBounds.lower.isEmpty() && !typeParamBounds.upper.isEmpty() + ? upperBound + : lowerBound; + return inferredType; + } } static Constraints addSubtypeConstraint( |
