NullAway icon indicating copy to clipboard operation
NullAway copied to clipboard

Undetected `@Nullable` annotation in a method reference

Open sdeleuze opened this issue 10 months ago • 2 comments

With the JSpecify mode enabled, I have this interface:

public interface WebFluxConfigurer {

	default @Nullable WebSocketService getWebSocketService() {
		return null;
	}
}

And:

	public @Nullable WebSocketService getWebSocketService() {
		return createSingleBean(WebFluxConfigurer::getWebSocketService, WebSocketService.class);
	}

	private <T> @Nullable T createSingleBean(Function<WebFluxConfigurer, @Nullable T> factory, Class<T> beanType) {
		// ...
	}

I get the following IMO invalid error:

error: [NullAway] Cannot pass parameter of type Function<WebFluxConfigurer, WebSocketService>, as formal parameter has type Function<WebFluxConfigurer, @org.jspecify.annotations.Nullable T>, which has mismatched type parameter nullability

sdeleuze avatar Jan 13 '25 14:01 sdeleuze

I can reproduce this one. It's not about default methods, but the fact that the call is to a generic method and we don't handle the instances of @Nullable T correctly. This one will be a bit trickier to fix and will take a bit; probably best to just suppress for now.

msridhar avatar Jan 31 '25 04:01 msridhar

As suggested here by @msridhar, I'm sharing a test case that may be relevant to this issue:

import static com.google.common.collect.ImmutableTable.toImmutableTable;

import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import java.util.stream.Stream;

final class Test {
  ImmutableTable<String, String, String> m() {
    return Stream.of(Tables.immutableCell("foo", "bar", "baz"))
        .collect(
            toImmutableTable(
                Table.Cell::getRowKey, Table.Cell::getColumnKey, Table.Cell::getValue));
  }
}

This triggers the following warnings:

[WARNING] /path/to/Test.java:[15,17] [NullAway] referenced method returns @Nullable, but functional interface method java.util.function.Function.apply(T) returns @NonNull
    (see http://t.uber.com/nullaway )
[WARNING] /path/to/Test.java:[15,40] [NullAway] referenced method returns @Nullable, but functional interface method java.util.function.Function.apply(T) returns @NonNull
    (see http://t.uber.com/nullaway )
[WARNING] /path/to/Test.java:[15,66] [NullAway] referenced method returns @Nullable, but functional interface method java.util.function.Function.apply(T) returns @NonNull
    (see http://t.uber.com/nullaway )

This happens only in JSpecify mode. The three flagged methods have had @ParametricNullness for four years, but the issue only reproduces with Guava 33.4.1-jre and above, likely because in that version @ElementTypesAreNonnullByDefault was replaced with @NullMarked.

Stephan202 avatar Mar 22 '25 18:03 Stephan202

This happens only in JSpecify mode.

@msridhar Should probably be tagged with the jspecify label.

sdeleuze avatar Oct 01 '25 09:10 sdeleuze