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 {