aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-01-07 18:05:55 +0000
committerMichael Williamson <mike@zwobble.org>2024-01-07 18:06:59 +0000
commit2d3d2c5f27a38c25e6d697c8635c38655f1a9728 (patch)
tree602f0f69cdf3747b4ca7bdd244368cf0adbdadcd /src/main/java
parent870aa25e96683a6686b019e40e1fe611fd36c69f (diff)
Update commonSupertype to handle supertype of sum and its variants
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java14
-rw-r--r--src/main/java/org/shedlang/compiler/types/Types.java7
2 files changed, 13 insertions, 8 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java b/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java
index ff2e0aad..3910b472 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeInfos.java
@@ -131,12 +131,18 @@ public class TypeInfos {
};
}
- public Set<SumType> supertypes(Type type) {
+ /**
+ * Get the supertypes of a type, from most specific to least specific.
+ */
+ public Set<Type> supertypes(Type type) {
+ var supertypes = P.set(type);
if (type instanceof StructType structType) {
- return this.structSupertypes.getOrDefault(structType, P.orderedSet());
- } else {
- return P.set();
+ supertypes = supertypes.plusAll(
+ this.structSupertypes.getOrDefault(structType, P.orderedSet())
+ );
}
+ supertypes.plus(Types.TOP);
+ return supertypes;
}
private Optional<SumTypeInfo> simpleSumTypeInfo(SimpleSumType type) {
diff --git a/src/main/java/org/shedlang/compiler/types/Types.java b/src/main/java/org/shedlang/compiler/types/Types.java
index 2e5f2562..59d1f96e 100644
--- a/src/main/java/org/shedlang/compiler/types/Types.java
+++ b/src/main/java/org/shedlang/compiler/types/Types.java
@@ -83,15 +83,14 @@ public class Types {
public static Type commonSupertype(List<Type> subtypes, TypeInfos typeInfos) {
var uniqueSubtypes = subtypes.stream()
.filter(subtype -> subtype != Types.BOTTOM)
- .collect(Collectors.toSet());
+ .distinct()
+ .toList();
if (uniqueSubtypes.isEmpty()) {
return BOTTOM;
- } else if (uniqueSubtypes.size() == 1) {
- return uniqueSubtypes.iterator().next();
}
- for (var supertype : typeInfos.supertypes(uniqueSubtypes.iterator().next())) {
+ for (var supertype : typeInfos.supertypes(uniqueSubtypes.getFirst())) {
if (uniqueSubtypes.stream().allMatch(subtype -> isSubType(subtype, supertype, typeInfos))) {
return supertype;
}