NullAway icon indicating copy to clipboard operation
NullAway copied to clipboard

JSpecify: support generic methods

Open beatbrot opened this issue 1 year ago • 1 comments

According to the JSpecify Spec, it is possible to add extends @Nullable Object to type parameters to siginify that T can be a nullable type.

Consider the following sample:

import org.jspecify.annotations.*;

@NullMarked
public class Todo {
    public static <T extends @Nullable Object> T foo(NullableSupplier<T> code) {
        return code.get();
    }

    public static void main(String[] args) {
        Todo.<@Nullable Object> foo(() -> null);
    }

    @NullMarked
    @FunctionalInterface
    public interface NullableSupplier<T extends @Nullable Object> {
        T get();
    }
}

According to JSpecify Spec, this is valid since the call to foo in main explicitly specifies the type parameter T as nullable Object. The JSpecify Reference Checker also accepts this. NullAway however falsly gives us the following error without JSpecifyMode:

Todo.java:13: error: [NullAway] returning @Nullable expression from method with @NonNull return type
        Todo.<@Nullable Object> foo(() -> null);
                                    ^
    (see http://t.uber.com/nullaway )
1 error

And this error with JSpecifyMode:

Todo.java:13: error: [NullAway] Cannot pass parameter of type NullableSupplier<@Nullable Object>, as formal parameter has type NullableSupplier<T>, which has mismatched type parameter nullability
        Todo.<@Nullable Object> foo(() -> null);
                                    ^
    (see http://t.uber.com/nullaway )
1 error

This issue seems similar to #660 and others, but I feel like my example gives a proper way to verify that this is a Bug and that the Bug would be resolved if my sample compiles.

beatbrot avatar Sep 09 '24 11:09 beatbrot

Hi @beatbrot thanks for the report. We currently have no support for generic methods in JSpecify mode, only generic classes. See further details here: https://github.com/uber/NullAway/wiki/JSpecify-Support We are actively working on this and hope to have more support within the next few months. I will update this issue when something is implemented.

msridhar avatar Sep 09 '24 21:09 msridhar

I'm happy to report that with the latest fixes from @haewiful the test case in this issue now passes in JSpecify mode! See #1074. Note that the test only passes with an explicit type argument at the call. I'm going to close this issue with that test, and open a new issue for supporting inference so that the type argument need not be written.

msridhar avatar Nov 14 '24 00:11 msridhar