From 4d23df42c629e84612768080448a3a24091369a9 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Sat, 14 Feb 2026 17:55:58 -0800 Subject: [PATCH 1/4] test case --- .../com/uber/nullaway/ContractsTests.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java b/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java index c3fe352579..09179ccd13 100644 --- a/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java @@ -439,6 +439,52 @@ void test(java.util.function.Function fun) { .doTest(); } + @Test + public void issue1453() { + makeTestHelperWithArgs( + withJSpecifyModeArgs( + Arrays.asList( + "-d", + temporaryFolder.getRoot().getAbsolutePath(), + "-XepOpt:NullAway:OnlyNullMarked=true"))) + .addSourceLines( + "NullUtil.java", + """ + package org.chromium.build; + import org.jspecify.annotations.NullMarked; + import org.jspecify.annotations.Nullable; + import org.jetbrains.annotations.Contract; + @NullMarked + public class NullUtil { + @SuppressWarnings("NullAway") + @Contract("null -> fail") + public static T assumeNonNull(@Nullable T object) { + return object; + } + } + """) + .addSourceLines( + "Test.java", + """ + package com.uber; + import java.util.List; + import org.jspecify.annotations.NullMarked; + import org.jspecify.annotations.Nullable; + import static org.chromium.build.NullUtil.assumeNonNull; + import java.util.concurrent.atomic.AtomicReference; + @NullMarked + class Test { + private final AtomicReference<@Nullable List> ref = new AtomicReference<>(); + void test() { + for (String s: assumeNonNull(ref.get())) { + System.out.println(s); + } + } + } + """) + .doTest(); + } + @Test public void contractPureOnlyIgnored() { makeTestHelperWithArgs( From 04ab8eaed5c3181a4d367b2269a903d322caa155 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Sat, 14 Feb 2026 18:28:13 -0800 Subject: [PATCH 2/4] fix --- .../nullaway/generics/GenericsChecks.java | 9 +++- .../com/uber/nullaway/ContractsTests.java | 46 ------------------- .../nullaway/jspecify/GenericMethodTests.java | 40 ++++++++++++++++ 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java b/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java index 2e397298ab..6f6cb10bac 100644 --- a/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java +++ b/nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java @@ -729,7 +729,14 @@ private MethodInferenceResult runInferenceForCall( methodSymbol, invocationTree, allInvocations); - typeVarNullability = solver.solve(); + typeVarNullability = new HashMap<>(solver.solve()); + // The solver only computes a solution for variables that appear in constraints. For + // unconstrained variables, treat them as NONNULL, consistent with solver behavior for + // unconstrained variables that do appear in the constraint graph. + for (int i = 0; i < methodSymbol.getTypeParameters().size(); i++) { + Symbol.TypeVariableSymbol typeVar = methodSymbol.getTypeParameters().get(i); + typeVarNullability.putIfAbsent(typeVar, ConstraintSolver.InferredNullability.NONNULL); + } // Store inferred types for lambda arguments new InvocationArguments(invocationTree, methodSymbol.type.asMethodType()) diff --git a/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java b/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java index 09179ccd13..c3fe352579 100644 --- a/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/ContractsTests.java @@ -439,52 +439,6 @@ void test(java.util.function.Function fun) { .doTest(); } - @Test - public void issue1453() { - makeTestHelperWithArgs( - withJSpecifyModeArgs( - Arrays.asList( - "-d", - temporaryFolder.getRoot().getAbsolutePath(), - "-XepOpt:NullAway:OnlyNullMarked=true"))) - .addSourceLines( - "NullUtil.java", - """ - package org.chromium.build; - import org.jspecify.annotations.NullMarked; - import org.jspecify.annotations.Nullable; - import org.jetbrains.annotations.Contract; - @NullMarked - public class NullUtil { - @SuppressWarnings("NullAway") - @Contract("null -> fail") - public static T assumeNonNull(@Nullable T object) { - return object; - } - } - """) - .addSourceLines( - "Test.java", - """ - package com.uber; - import java.util.List; - import org.jspecify.annotations.NullMarked; - import org.jspecify.annotations.Nullable; - import static org.chromium.build.NullUtil.assumeNonNull; - import java.util.concurrent.atomic.AtomicReference; - @NullMarked - class Test { - private final AtomicReference<@Nullable List> ref = new AtomicReference<>(); - void test() { - for (String s: assumeNonNull(ref.get())) { - System.out.println(s); - } - } - } - """) - .doTest(); - } - @Test public void contractPureOnlyIgnored() { makeTestHelperWithArgs( diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java index d53ab579bb..f86a72cdb8 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java @@ -1528,6 +1528,46 @@ public static T notNull(@Nullable T object, String message) { .doTest(); } + @Test + public void issue1453() { + makeHelper() + .addSourceLines( + "NullUtil.java", + """ + package com.uber; + import org.jspecify.annotations.NullMarked; + import org.jspecify.annotations.Nullable; + import org.jetbrains.annotations.Contract; + @NullMarked + public class NullUtil { + @SuppressWarnings("NullAway") + public static T assumeNonNull(@Nullable T object) { + return object; + } + } + """) + .addSourceLines( + "Test.java", + """ + package com.uber; + import java.util.List; + import org.jspecify.annotations.NullMarked; + import org.jspecify.annotations.Nullable; + import static com.uber.NullUtil.assumeNonNull; + import java.util.concurrent.atomic.AtomicReference; + @NullMarked + class Test { + private final AtomicReference<@Nullable List> ref = new AtomicReference<>(); + void test() { + for (String s: assumeNonNull(ref.get())) { + System.out.println(s); + } + } + } + """) + .doTest(); + } + private CompilationTestHelper makeHelper() { return makeTestHelperWithArgs( JSpecifyJavacConfig.withJSpecifyModeArgs( From a1e018a23e86bda70a76f671c1a3c5fb8541d1d5 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Sat, 14 Feb 2026 18:33:02 -0800 Subject: [PATCH 3/4] Update nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../com/uber/nullaway/jspecify/GenericMethodTests.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java index f86a72cdb8..b8d57609ba 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java @@ -1537,11 +1537,10 @@ public void issue1453() { package com.uber; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; - import org.jetbrains.annotations.Contract; - @NullMarked + `@NullMarked` public class NullUtil { - @SuppressWarnings("NullAway") - public static T assumeNonNull(@Nullable T object) { + `@SuppressWarnings`("NullAway") + public static T assumeNonNull(`@Nullable` T object) { return object; } } From f522f7b1a107749e8b189d1a3e67e01076915144 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Sat, 14 Feb 2026 18:44:36 -0800 Subject: [PATCH 4/4] fix --- .../java/com/uber/nullaway/jspecify/GenericMethodTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java index b8d57609ba..1ac0bdb378 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericMethodTests.java @@ -1537,10 +1537,10 @@ public void issue1453() { package com.uber; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; - `@NullMarked` + @NullMarked public class NullUtil { - `@SuppressWarnings`("NullAway") - public static T assumeNonNull(`@Nullable` T object) { + @SuppressWarnings("NullAway") + public static T assumeNonNull(@Nullable T object) { return object; } }