You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix JSpecify false negative when override narrows method type variable bound (#1682)
## Summary
Fixes#1512.
In JSpecify mode, NullAway did not compare method type-variable
upper-bound nullability between an overriding method and the method it
overrides. That allowed unsound overrides such as:
```java
@NullMarked
interface Foo {
<T extends @nullable Object> void bar(T arg);
}
@NullMarked
class Baz implements Foo {
@OverRide
public <T> void bar(T arg) { arg.hashCode(); } // was accepted
}
```
Callers can still invoke the method via the super type with a
`@Nullable` type argument (e.g. `f.<@nullable String>bar(null)`), so
treating the override's parameter as non-null is incorrect.
This change, in
`GenericsChecks.checkTypeParameterNullnessForMethodOverriding`, compares
upper-bound nullability of corresponding method type variables (using
`GenericsUtils.upperBoundIsNullable`) and reports
`WRONG_OVERRIDE_PARAM_GENERIC` when they differ—whether the override
narrows `@Nullable` → non-null or widens non-null → `@Nullable`.
## Tests
- `overrideNarrowsNullableMethodTypeVariableBound` — issue #1512 repro
(param position)
- `overrideWidensNonNullMethodTypeVariableBound` — reverse mismatch
- `overridePreservesNullableMethodTypeVariableBound` /
`overridePreservesNonNullMethodTypeVariableBound` — matching bounds
remain legal
- `overrideNarrowsNullableMethodTypeVariableBoundOnReturn` — return-only
type variable
```bash
./gradlew :nullaway:test --tests "com.uber.nullaway.jspecify.GenericMethodTests"
./gradlew :nullaway:test --tests "com.uber.nullaway.jspecify.*"
```
(JDK 21)
## AI disclosure
I used AI tools (Grok) to help draft the fix and tests. I reviewed all
changes, ran the tests above, and understand the code.
- [x] Description of what and why
- [x] Issue number: #1512
- [x] Unit tests
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved validation of generic method overrides with nullable and
non-null type-variable bounds.
* Reports clearer diagnostics when an override narrows or widens a bound
incompatibly.
* Correctly accepts overrides that preserve compatible bounds, including
substituted nullable types and return-type variables.
* Skips bound validation for unannotated methods and mismatched
type-variable declarations.
* **Tests**
* Added regression coverage for narrowed, widened, and preserved generic
nullability bounds across parameters and return types.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: arimu1 <19286898+arimu1@users.noreply.github.com>
0 commit comments