blob: b09cf0347cd012e22c811ff8fe22c49ec67e2450 [file] [view] [edit]
Nullness annotations directly on wildcard types are interpreted differently by
different tools.
unless you are using the Checker Framework.
### Tool interpretations and suggested alternatives
#### `Foo<@Nullable ?>`
To the Checker Framework, this means that the type argument *must* be nullable.
They use this
[in `ExecutorService`](https://github.com/typetools/jdk/blob/1973fa0811588dd0bb025fdc99345cdb887b3b52/src/java.base/share/classes/java/util/concurrent/ExecutorService.java#L269).
To Kotlin, this [has no effect][KT-40498]. That means that the type argument
*can* be nullable but need not be so.
While Checker Framework users do sometimes want `Foo<@Nullable ?>`, we commonly
see them use it in places where `Foo<?>` would also be correct and would be more
flexible. To fully preserve Kotlin behavior, Kotlin users may wish to write
"`Foo<? extends @Nullable Object>`" (unless they are within the scope of
`@NullMarked`, in which case `Foo<?>` is equivalent).
The effects of that change would be:
* It is a behavior change for the Checker Framework, one that could produce
local or non-local the Checker Framework failures. But it's likely to be a
desirable change except in the context of `ExecutorService` and the `Future`
objects that it produces.
* `Foo<?>` is probably not a behavior change for Kotlin.
#### `Foo<@NonNull ?>`
To the Checker Framework, this means that the type argument must be
non-nullable. (See
[the Checker Framework docs](https://checkerframework.org/manual/#annotations-on-wildcards).)
To Kotlin, this [has no effect][KT-40498]. That means that the type argument can
still be nullable.
We recommend a change to `Foo<? extends @NonNull Object>` (or, within the scope
of `@NullMarked`, `Foo<? extends Object>`).
The effects of that change would be:
* It is a no-op for the Checker Framework.
* It could produce errors for Kotlin users. But these errors are likely to be
what was intended all along.
### JSpecify specification
The JSpecify spec says that usages of their annotations on wildcard types are
unrecognized
([Javadoc](https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html#applicability),
[spec](https://jspecify.dev/docs/spec/#recognized-locations-for-type-use-annotations)).
This specification choice is motivated by the disagreement in tool behavior
discussed above.
[KT-40498]: https://youtrack.jetbrains.com/issue/KT-40498/Nullability-annotations-on-Java-wildcard-itself