You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2025/05/31 17:11:28 UTC

(groovy) branch GROOVY-11685 created (now 67af81026f)

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a change to branch GROOVY-11685
in repository https://gitbox.apache.org/repos/asf/groovy.git


      at 67af81026f GROOVY-11685: STC: `null` or `void` return within closure expression

This branch includes the following new commits:

     new 67af81026f GROOVY-11685: STC: `null` or `void` return within closure expression

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(groovy) 01/01: GROOVY-11685: STC: `null` or `void` return within closure expression

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-11685
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 67af81026f39e8c27c98b87901bb54e5b2a4fec8
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat May 31 11:37:17 2025 -0500

    GROOVY-11685: STC: `null` or `void` return within closure expression
---
 .../groovy/transform/stc/StaticTypeCheckingVisitor.java |  5 +++--
 .../groovy/groovy/transform/stc/ClosuresSTCTest.groovy  | 17 +++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index fa7df3da1e..2605a17e2e 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2397,7 +2397,7 @@ out:    if ((samParameterTypes.length == 1 && isOrImplements(samParameterTypes[0
 
     protected ClassNode checkReturnType(final ReturnStatement statement) {
         Expression expression = statement.getExpression();
-        ClassNode type = getType(expression);
+        var type = statement.isReturningNullOrVoid() ? VOID_TYPE : getType(expression); // GROOVY-11685
 
         TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
         if (enclosingClosure != null) {
@@ -2419,7 +2419,8 @@ out:    if ((samParameterTypes.length == 1 && isOrImplements(samParameterTypes[0
                 } else if (statement.isReturningNullOrVoid() ? !isPrimitiveType(inferredReturnType) // GROOVY-7713, GROOVY-8202
                      : GenericsUtils.buildWildcardType(wrapTypeIfNecessary(inferredReturnType)).isCompatibleWith(wrapTypeIfNecessary(type))) {
                     type = inferredReturnType; // GROOVY-8310, GROOVY-10082, GROOVY-10091, GROOVY-10128, GROOVY-10306: allow simple covariance
-                } else if (!isPrimitiveVoid(type) && !extension.handleIncompatibleReturnType(statement, type)) { // GROOVY-10277: incompatible
+                } else if ((statement.isReturningNullOrVoid() || !isPrimitiveVoid(type)) && !extension.handleIncompatibleReturnType(statement, type)) {
+                    // GROOVY-10277, GROOVY-11490: incompatible return statement (null for primitive or inconvertible type)
                     String value = (statement.isReturningNullOrVoid() ? "null" : "value of type " + prettyPrintType(type));
                     String which = (enclosingClosure.getClosureExpression() instanceof LambdaExpression ? "lambda" : "closure");
                     addStaticTypeError("Cannot return " + value + " for " + which + " expecting " + prettyPrintType(inferredReturnType), expression);
diff --git a/src/test/groovy/groovy/transform/stc/ClosuresSTCTest.groovy b/src/test/groovy/groovy/transform/stc/ClosuresSTCTest.groovy
index 3bec5b2998..856cc3c4bd 100644
--- a/src/test/groovy/groovy/transform/stc/ClosuresSTCTest.groovy
+++ b/src/test/groovy/groovy/transform/stc/ClosuresSTCTest.groovy
@@ -429,6 +429,23 @@ class ClosuresSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-11685
+    void testCollect3() {
+        assertScript '''
+            List<Number> test(List<String> strings) {
+                List<Number> numbers = []
+                if (true) {
+                    numbers = strings.collect { string ->
+                        if (!string.isNumber()) return
+                        (Number) Integer.parseInt(string)
+                    }
+                }
+                numbers
+            }
+            assert test(['1','2','3','x']) == [1,2,3,null]
+        '''
+    }
+
     void testWithIntReturnType() {
         assertScript '''
             class Test {