Skip to content

Commit 9a8a33b

Browse files
authored
GROOVY-11685: STC: null or void return within closure expression (#2243)
1 parent 6f97a5b commit 9a8a33b

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,7 +2397,7 @@ public void visitReturnStatement(final ReturnStatement statement) {
23972397

23982398
protected ClassNode checkReturnType(final ReturnStatement statement) {
23992399
Expression expression = statement.getExpression();
2400-
ClassNode type = getType(expression);
2400+
var type = statement.isReturningNullOrVoid() ? VOID_TYPE : getType(expression); // GROOVY-11685
24012401

24022402
TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
24032403
if (enclosingClosure != null) {
@@ -2419,7 +2419,8 @@ protected ClassNode checkReturnType(final ReturnStatement statement) {
24192419
} else if (statement.isReturningNullOrVoid() ? !isPrimitiveType(inferredReturnType) // GROOVY-7713, GROOVY-8202
24202420
: GenericsUtils.buildWildcardType(wrapTypeIfNecessary(inferredReturnType)).isCompatibleWith(wrapTypeIfNecessary(type))) {
24212421
type = inferredReturnType; // GROOVY-8310, GROOVY-10082, GROOVY-10091, GROOVY-10128, GROOVY-10306: allow simple covariance
2422-
} else if (!isPrimitiveVoid(type) && !extension.handleIncompatibleReturnType(statement, type)) { // GROOVY-10277: incompatible
2422+
} else if ((statement.isReturningNullOrVoid() || !isPrimitiveVoid(type)) && !extension.handleIncompatibleReturnType(statement, type)) {
2423+
// GROOVY-10277, GROOVY-11490: incompatible return statement (null for primitive or inconvertible type)
24232424
String value = (statement.isReturningNullOrVoid() ? "null" : "value of type " + prettyPrintType(type));
24242425
String which = (enclosingClosure.getClosureExpression() instanceof LambdaExpression ? "lambda" : "closure");
24252426
addStaticTypeError("Cannot return " + value + " for " + which + " expecting " + prettyPrintType(inferredReturnType), expression);

src/test/groovy/groovy/transform/stc/ClosuresSTCTest.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,23 @@ class ClosuresSTCTest extends StaticTypeCheckingTestCase {
429429
'''
430430
}
431431

432+
// GROOVY-11685
433+
void testCollect3() {
434+
assertScript '''
435+
List test(List strings) {
436+
List numbers = []
437+
if (true) {
438+
numbers = strings.collect { string ->
439+
if (!string.isNumber()) return
440+
(Number) Integer.parseInt(string)
441+
}
442+
}
443+
numbers
444+
}
445+
assert test(['1','2','3','x']) == [1,2,3,null]
446+
'''
447+
}
448+
432449
void testWithIntReturnType() {
433450
assertScript '''
434451
class Test {

0 commit comments

Comments
 (0)