JSpecify: some calls to constructor / super not handled correctly
Here's an example with subclasses:
import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; @NullMarked class Foo { interface Supplier<T extends @Nullable Object> { T get(); } static class SupplierImpl<T2 extends @Nullable Object> implements Supplier<T2> { Supplier<T2> impl; SupplierImpl(Supplier<T2> delegate) { impl = delegate; } @Override public T2 get() { return impl.get(); } } static class ConcreteImpl extends SupplierImpl<@Nullable Foo> { ConcreteImpl(Supplier<@Nullable Foo> delegate) { super(delegate); } } }yields:
Foo.java:24: warning: [NullAway] Cannot pass parameter of type Supplier<@Nullable Foo>, as formal parameter has type Supplier<T2>, which has mismatched type parameter nullability super(delegate); ^ (see http://t.uber.com/nullaway )Or alternatively, replacing
ConcreteImplwith:static void main() { Supplier<@Nullable Foo> sup = () -> null; new SupplierImpl<@Nullable Foo>(sup); }yields:
Foo.java:24: warning: [NullAway] Cannot pass parameter of type Supplier<@Nullable Foo>, as formal parameter has type Supplier<T2>, which has mismatched type parameter nullability new SupplierImpl<@Nullable Foo>(sup);
Originally posted by @agrieve in #1209
Another simple example (which I'm not sure is the same or not):
@NullMarked
class Foo {
static void main() {
FutureTask<@Nullable Void> task = new FutureTask<@Nullable Void>(() -> {}, null);
}
}
Foo.java:8: warning: [NullAway] passing @Nullable parameter 'null' where @NonNull is required
FutureTask<@Nullable Void> task = new FutureTask<>(() -> {}, null);
This is with a library model that sets:
public ImmutableSetMultimap<String, Integer> typeVariablesWithNullableUpperBounds() {
return new ImmutableSetMultimap.Builder<String, Integer>()
.put("java.util.concurrent.FutureTask", 0).build();
}
public ImmutableSet<String> nullMarkedClasses() {
return typeVariablesWithNullableUpperBounds().keySet();
}
Oh, happens without library model as well:
import org.chromium.build.annotations.Nullable;
import org.chromium.build.annotations.NullMarked;
@NullMarked
class Foo {
static class Example<T extends @Nullable Object> {
Example(T thing) {}
}
static void main() {
Example<@Nullable Void> example = new Example<>(null);
}
}
Currently our handling of the diamond operator on constructor calls is limited / non-existent. So that might be the issue here? Sorry, we should document that better.
This has the same warning if I fill in the generics:
static void main() {
Example<@Nullable Void> example = new Example<@Nullable Void>(null);
}
This has the same warning if I fill in the generics:
static void main() { Example<@Nullable Void> example = new Example<@Nullable Void>(null); }
This might get fixed by #1210
Modulo handling of the diamond operator, I think the issues from the examples here are fixed, so I'm going to close this one.