aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-01-13 17:32:10 +0000
committerMichael Williamson <mike@zwobble.org>2024-01-13 17:32:10 +0000
commitc109b45a80078e306d983b27c91e31a0cae50eac (patch)
tree2101782467264db2816a76a74ae708f2785b9539 /src/main/java
parentf5ba39cf70de72ae727c23df49b842a608dd4aaf (diff)
Update commonSubtype() to produce more specific types
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java10
-rw-r--r--src/main/java/org/shedlang/compiler/types/Types.java24
2 files changed, 22 insertions, 12 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java
index b17758b3..3a7c026b 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeCheckerSubTyping.java
@@ -81,12 +81,18 @@ public class TypeCheckerSubTyping {
var lowerBound = Types.BOTTOM;
for (var lower : typeParamBounds.lower) {
- lowerBound = Types.commonSupertype(List.of(lowerBound, lower), this.typeInfos);
+ 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));
+ upperBound = Types.commonSubtype(
+ List.of(upperBound, upper),
+ this.typeInfos
+ );
}
if (!isSubType(lowerBound, upperBound, typeInfos)) {
diff --git a/src/main/java/org/shedlang/compiler/types/Types.java b/src/main/java/org/shedlang/compiler/types/Types.java
index 59d1f96e..2abf4df0 100644
--- a/src/main/java/org/shedlang/compiler/types/Types.java
+++ b/src/main/java/org/shedlang/compiler/types/Types.java
@@ -3,7 +3,6 @@ package org.shedlang.compiler.types;
import org.shedlang.compiler.typechecker.TypeInfos;
import java.util.List;
-import java.util.stream.Collectors;
import static org.shedlang.compiler.typechecker.TypeCheckerSubTyping.isSubType;
@@ -99,17 +98,22 @@ public class Types {
return TOP;
}
- public static Type commonSubtype(List<Type> supertypes) {
- var uniqueSubtypes = supertypes.stream()
- .filter(subtype -> subtype != Types.TOP)
- .collect(Collectors.toSet());
+ public static Type commonSubtype(List<Type> supertypes, TypeInfos typeInfos) {
+ var uniqueSupertypes = supertypes.stream()
+ .filter(supertype -> supertype != Types.TOP)
+ .distinct()
+ .toList();
- if (uniqueSubtypes.isEmpty()) {
+ if (uniqueSupertypes.isEmpty()) {
return TOP;
- } else if (uniqueSubtypes.size() == 1) {
- return uniqueSubtypes.iterator().next();
- } else {
- return BOTTOM;
}
+
+ for (var subtype : typeInfos.subtypes(uniqueSupertypes.getFirst())) {
+ if (uniqueSupertypes.stream().allMatch(supertype -> isSubType(subtype, supertype, typeInfos))) {
+ return subtype;
+ }
+ }
+
+ return BOTTOM;
}
}