Skip to content

Fix NPE in VarWithPrimitive when lambda parameters have inferred primitive types#5873

Open
copybara-service[bot] wants to merge 1 commit into
masterfrom
test_931039338
Open

Fix NPE in VarWithPrimitive when lambda parameters have inferred primitive types#5873
copybara-service[bot] wants to merge 1 commit into
masterfrom
test_931039338

Conversation

@copybara-service

Copy link
Copy Markdown
Contributor

Fix NPE in VarWithPrimitive when lambda parameters have inferred primitive types

Problem

Fixes #5857

VarWithPrimitive throws a NullPointerException when a lambda has an implicit
parameter whose inferred type is a primitive:

byte[] bar = new byte[6];
Map<Byte, List<Byte>> indicesMap =
    IntStream.range(0, 6)
        .mapToObj(n -> n)
        .collect(Collectors.groupingBy(
            n -> bar[n],
            Collectors.mapping(
                n -> (byte) n.intValue(),
                Collectors.toList())));

// Exception:
java.lang.NullPointerException: Cannot invoke
"com.sun.tools.javac.tree.JCTree.getStartPosition()"
because "tree" is null

Root Cause

hasImplicitType() returns true for both:

  • var declarations
  • Implicit lambda parameters (when VariableTree.getType() is null, per JDK-8268850)

VarWithPrimitive used hasImplicitType() as its guard, so lambda parameters
with inferred primitive types passed the check and reached
replaceVariableType().

Inside replaceVariableType(), tree.getType() returns null for these
parameters. hasExplicitSource(null, state) was then called unconditionally,
which invokes:

getStartPosition(null)

resulting in a NullPointerException.

Fix

Add a null guard for type in SuggestedFixes.replaceVariableType() at the
actual crash site.

If type == null:

  • Skip the hasExplicitSource() call.
  • Fall through to getStartPosition(tree).

The subsequent token scan finds no var keyword for implicit lambda
parameters and correctly returns Optional.empty(), producing NO_MATCH
without throwing an exception.

This is the minimal fix because:

  • It addresses the actual crash site.
  • It is defensive against any other callers that may pass a VariableTree
    with a null type.

Tests

implicitLambdaParameter_noMatch

Regression test reproducing the exact code from the bug report:

  • Single-parameter lambdas
  • Inferred int and byte types
  • Verifies NO_MATCH and no exception

multiParamImplicitLambda_noMatch

Tests a multi-parameter implicit lambda:

IntBinaryOperator op = (a, b) -> a + b;
  • Both parameters inferred as int
  • Verifies NO_MATCH and no exception

explicitLambdaParam_noMatch

Tests an explicit lambda parameter:

(int n) -> n
  • hasImplicitType() returns false
  • Verifies no match is reported

enhancedForLoop

Tests:

for (var x : intArray) {
    // ...
}

Expected fix:

for (int x : intArray) {
    // ...
}

forLoopInitializer

Tests:

for (var i = 0; i < 10; i++) {
    // ...
}

Expected fix:

for (int i = 0; i < 10; i++) {
    // ...
}

Fixes #5868

FUTURE_COPYBARA_INTEGRATE_REVIEW=#5868 from HarshMehta112:master 5881069

@copybara-service copybara-service Bot force-pushed the test_931039338 branch 4 times, most recently from cdfcdfb to 1fff859 Compare June 12, 2026 21:56
…imitive types

## Problem

Fixes #5857

`VarWithPrimitive` throws a `NullPointerException` when a lambda has an implicit
parameter whose inferred type is a primitive:

```java
byte[] bar = new byte[6];
Map<Byte, List<Byte>> indicesMap =
    IntStream.range(0, 6)
        .mapToObj(n -> n)
        .collect(Collectors.groupingBy(
            n -> bar[n],
            Collectors.mapping(
                n -> (byte) n.intValue(),
                Collectors.toList())));

// Exception:
java.lang.NullPointerException: Cannot invoke
"com.sun.tools.javac.tree.JCTree.getStartPosition()"
because "tree" is null
```

## Root Cause

`hasImplicitType()` returns `true` for both:

- `var` declarations
- Implicit lambda parameters (when `VariableTree.getType()` is `null`, per JDK-8268850)

`VarWithPrimitive` used `hasImplicitType()` as its guard, so lambda parameters
with inferred primitive types passed the check and reached
`replaceVariableType()`.

Inside `replaceVariableType()`, `tree.getType()` returns `null` for these
parameters. `hasExplicitSource(null, state)` was then called unconditionally,
which invokes:

```java
getStartPosition(null)
```

resulting in a `NullPointerException`.

## Fix

Add a null guard for `type` in `SuggestedFixes.replaceVariableType()` at the
actual crash site.

If `type == null`:

- Skip the `hasExplicitSource()` call.
- Fall through to `getStartPosition(tree)`.

The subsequent token scan finds no `var` keyword for implicit lambda
parameters and correctly returns `Optional.empty()`, producing `NO_MATCH`
without throwing an exception.

This is the minimal fix because:

- It addresses the actual crash site.
- It is defensive against any other callers that may pass a `VariableTree`
  with a null type.

## Tests

### `implicitLambdaParameter_noMatch`

Regression test reproducing the exact code from the bug report:

- Single-parameter lambdas
- Inferred `int` and `byte` types
- Verifies `NO_MATCH` and no exception

### `multiParamImplicitLambda_noMatch`

Tests a multi-parameter implicit lambda:

```java
IntBinaryOperator op = (a, b) -> a + b;
```

- Both parameters inferred as `int`
- Verifies `NO_MATCH` and no exception

### `explicitLambdaParam_noMatch`

Tests an explicit lambda parameter:

```java
(int n) -> n
```

- `hasImplicitType()` returns `false`
- Verifies no match is reported

### `enhancedForLoop`

Tests:

```java
for (var x : intArray) {
    // ...
}
```

Expected fix:

```java
for (int x : intArray) {
    // ...
}
```

### `forLoopInitializer`

Tests:

```java
for (var i = 0; i < 10; i++) {
    // ...
}
```

Expected fix:

```java
for (int i = 0; i < 10; i++) {
    // ...
}
```

Fixes #5868

FUTURE_COPYBARA_INTEGRATE_REVIEW=#5868 from HarshMehta112:master 5881069
PiperOrigin-RevId: 931039338
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[VarWithPrimitive] java.lang.NullPointerException: Cannot invoke "com.sun.tools.javac.tree.JCTree.getStartPosition()" because "tree" is null

1 participant