From 90190801d932748535a0ab85039d9f45a6db5929 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 29 Oct 2023 18:26:34 +0000 Subject: Check use of block returns when inferring return types --- .../typechecker/TypeCheckerFunctionBodyTests.java | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionBodyTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionBodyTests.java index 8b7bc4f6..dbd860e7 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionBodyTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionBodyTests.java @@ -320,6 +320,58 @@ public class TypeCheckerFunctionBodyTests { ); } + @Test + public void givenNoExplicitReturnTypeWhenThereIsBlockReturnWithNoReturnStatementsThenReturnTypeIsTypeOfBlock() { + var untyped = Untyped.block(List.of( + Untyped.blockReturn(Untyped.stringLiteral("")) + )); + var signature = TypedFunctionSignatureNode.builder() + .withoutReturnType() + .build(); + var context = TypeCheckerContext.EMPTY; + + var typed = typeCheckFunctionBody(untyped, signature, context); + + assertThat( + typed.value(), + isTypedFunctionBodyNode() + .withType(Types.STRING) + ); + } + + @Test + public void givenNoExplicitReturnTypeWhenThereIsBlockReturnAndReturnStatementsThenReturnTypeIsCommonSupertypeOfReturnExpressions() { + var untyped = Untyped.block(List.of( + Untyped.expressionStatement(Untyped.if_( + List.of( + Untyped.conditionalBranch( + Untyped.reference("c"), + Untyped.block(List.of( + Untyped.functionReturn(Untyped.stringLiteral("")) + )) + ) + ), + Untyped.block(List.of()) + )), + Untyped.blockReturn(Untyped.intLiteral(0)) + )); + var signature = TypedFunctionSignatureNode.builder() + .withoutReturnType() + .build(); + var context = TypeCheckerContext.EMPTY + .enterGlobal(P.map( + Map.entry("c", Types.BOOL) + )); + + var typed = typeCheckFunctionBody(untyped, signature, context); + + assertThat( + typed.value(), + isTypedFunctionBodyNode() + .withType(Types.TOP) + ); + } + @Test public void freeVariablesIncludeVariablesReferencedInFunctionButDefinedOutsideOfFunction() { var untyped = Untyped.block(List.of( -- cgit v1.2.3