From 5f7d8b9685df150d2fb030ba523566d6e194ca39 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Tue, 26 Mar 2024 11:30:47 +0100 Subject: [PATCH] feat: allow any widening/narrowing type cast --- .../src/language/validation/types.ts | 12 +++++++++-- .../types/checking/type casts/main.sdstest | 21 +++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/safe-ds-lang/src/language/validation/types.ts b/packages/safe-ds-lang/src/language/validation/types.ts index c4be233ff..c9c70a572 100644 --- a/packages/safe-ds-lang/src/language/validation/types.ts +++ b/packages/safe-ds-lang/src/language/validation/types.ts @@ -354,12 +354,20 @@ export const prefixOperationOperandMustHaveCorrectType = (services: SafeDsServic }; export const typeCastExpressionMustHaveUnknownType = (services: SafeDsServices) => { + const typeChecker = services.types.TypeChecker; const typeComputer = services.types.TypeComputer; return (node: SdsTypeCast, accept: ValidationAcceptor): void => { const expressionType = typeComputer.computeType(node.expression); - if (node.expression && expressionType !== UnknownType) { - accept('error', 'Type casts can only be applied to expressions of unknown type.', { + const targetType = typeComputer.computeType(node.type); + + if ( + node.expression && + expressionType !== UnknownType && + !typeChecker.isSubtypeOf(expressionType, targetType) && + !typeChecker.isSupertypeOf(expressionType, targetType) + ) { + accept('error', 'This type cast can never succeed.', { // Using property: "expression" does not work here, probably due to eclipse-langium/langium#1218 node: node.expression, code: CODE_TYPE_MISMATCH, diff --git a/packages/safe-ds-lang/tests/resources/validation/types/checking/type casts/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/types/checking/type casts/main.sdstest index 10308aa48..1676dd928 100644 --- a/packages/safe-ds-lang/tests/resources/validation/types/checking/type casts/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/types/checking/type casts/main.sdstest @@ -1,9 +1,22 @@ package tests.validation.types.checking.typeCasts +class C() +class D() sub C +class E() sub C + pipeline test { - // $TEST$ no error "Type casts can only be applied to expressions of unknown type." - »unresolved« as Int; + // $TEST$ error "This type cast can never succeed." + »D()« as E; + + // $TEST$ no error "This type cast can never succeed." + »C()« as C; - // $TEST$ error "Type casts can only be applied to expressions of unknown type." - »1« as Int; + // $TEST$ no error "This type cast can never succeed." + »C()« as D; + + // $TEST$ no error "This type cast can never succeed." + »D()« as C; + + // $TEST$ no error "This type cast can never succeed." + »unresolved« as Int; }