From c109b45a80078e306d983b27c91e31a0cae50eac Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 13 Jan 2024 17:32:10 +0000 Subject: Update commonSubtype() to produce more specific types --- .../compiler/typechecker/TypeCheckerSubTyping.java | 10 +++++++-- .../java/org/shedlang/compiler/types/Types.java | 24 +++++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src/main/java') 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 supertypes) { - var uniqueSubtypes = supertypes.stream() - .filter(subtype -> subtype != Types.TOP) - .collect(Collectors.toSet()); + public static Type commonSubtype(List 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; } } -- cgit v1.2.3