diff --git a/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts b/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts index 87d4962aa..3e4b21d2e 100644 --- a/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts +++ b/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts @@ -75,7 +75,8 @@ export class SafeDsTypeChecker { // Handle union types if (type instanceof UnionType) { return type.types.every((it) => this.isSubtypeOf(it, other, options)); - } else if (other instanceof UnionType) { + } else if (other instanceof UnionType && !(type instanceof LiteralType)) { + // For literal types the quantifiers would be the wrong way around return other.types.some((it) => this.isSubtypeOf(type, it, options)); } @@ -264,17 +265,21 @@ export class SafeDsTypeChecker { return true; } - return type.constants.every((constant) => this.constantIsSubtypeOfClassType(constant, other, options)); + return type.constants.every((constant) => this.constantIsSubtypeOf(constant, other, options)); } else if (other instanceof LiteralType) { return type.constants.every((constant) => other.constants.some((otherConstant) => constant.equals(otherConstant)), ); + } else if (other instanceof UnionType) { + return type.constants.every((constant) => + other.types.some((it) => this.constantIsSubtypeOf(constant, it, options)), + ); } else { return false; } } - private constantIsSubtypeOfClassType(constant: Constant, other: ClassType, options: TypeCheckOptions): boolean { + private constantIsSubtypeOf(constant: Constant, other: Type, options: TypeCheckOptions): boolean { const classType = this.typeComputer().computeClassTypeForConstant(constant); return this.isSubtypeOf(classType, other, options); } diff --git a/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts b/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts index fdda32898..6c145f42b 100644 --- a/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts +++ b/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts @@ -508,6 +508,11 @@ const basic = async (): Promise => { type2: factory.createUnionType(coreTypes.String), expected: false, }, + { + type1: factory.createLiteralType(new IntConstant(1n), new StringConstant('')), + type2: factory.createUnionType(coreTypes.Int, coreTypes.String), + expected: true, + }, // Literal type to other { type1: factory.createLiteralType(), // Empty literal type