Skip to content

Commit

Permalink
GROOVY-11353: STC: def var = null; var = 0 requires wrapper type
Browse files Browse the repository at this point in the history
4_0_X backport
  • Loading branch information
eric-milles committed Sep 7, 2024
1 parent ab3bc99 commit f49c286
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,11 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {

boolean isEmptyDeclaration = (expression instanceof DeclarationExpression
&& (rightExpression instanceof EmptyExpression || rType == UNKNOWN_PARAMETER_TYPE));
if (!isEmptyDeclaration && isAssignment(op)) {
if (isEmptyDeclaration) {
// GROOVY-11353: "def var = null" cannot be a primitive type
if (isDynamicTyped(lType) && rType == UNKNOWN_PARAMETER_TYPE)
lType.putNodeMetaData("non-primitive type", Boolean.TRUE);
} else if (isAssignment(op)) {
if (rightExpression instanceof ConstructorCallExpression)
inferDiamondType((ConstructorCallExpression) rightExpression, lType);

Expand Down Expand Up @@ -921,10 +925,9 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {
}
if (!isEmptyDeclaration) {
storeType(expression, resultType);
validateResourceInARM(expression, resultType);
}

validateResourceInARM(expression, resultType);

// GROOVY-5874: if left expression is a closure shared variable, a second pass should be done
if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).isClosureSharedVariable()) {
typeCheckingContext.secondPassExpressions.add(new SecondPassExpression<>(expression));
Expand Down Expand Up @@ -4620,7 +4623,8 @@ protected ClassNode getResultType(ClassNode left, final int op, final ClassNode
if (leftExpression instanceof VariableExpression) {
ClassNode initialType = getOriginalDeclarationType(leftExpression);

if (isPrimitiveType(rightRedirect) && initialType.isDerivedFrom(Number_TYPE)) {
if (isPrimitiveType(rightRedirect) && (initialType.isDerivedFrom(Number_TYPE)
|| Boolean.TRUE.equals(initialType.getNodeMetaData("non-primitive type")))) { // GROOVY-11353
return getWrapper(right);
}

Expand Down
11 changes: 11 additions & 0 deletions src/test/groovy/transform/stc/STCAssignmentTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,17 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
'Cannot find matching method java.io.Serializable#toInteger()'
}

// GROOVY-11353
void testForLoopWithAssignment2() {
assertScript '''
def x = null // Cannot cast object 'null' to class 'int'
for (int i = 0; i < 1; i += 1) {
x = i
}
assert x == 0
'''
}

void testWhileLoopWithAssignment() {
shouldFailWithMessages '''
def x = '123'
Expand Down

0 comments on commit f49c286

Please sign in to comment.