From 933b1afbe0f8786caaa8ad8a3ed86e1b868a442a Mon Sep 17 00:00:00 2001
From: Manu Sridharan <msridhar@gmail.com>
Date: Thu, 12 Dec 2024 12:34:24 -0800
Subject: [PATCH] Fix another JSpecify mode crash involving raw types (#1086)

Fixes the second crash of #1082. Weird things can happen with raw
types...see the test case.
---
 .../CheckIdenticalNullabilityVisitor.java     |  6 ++---
 .../uber/nullaway/jspecify/GenericsTests.java | 25 +++++++++++++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java b/nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java
index 5f1bac2742..d567c2e028 100644
--- a/nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java
+++ b/nullaway/src/main/java/com/uber/nullaway/generics/CheckIdenticalNullabilityVisitor.java
@@ -35,10 +35,10 @@ public Boolean visitClassType(Type.ClassType lhsType, Type rhsType) {
     // The base type of rhsType may be a subtype of lhsType's base type.  In such cases, we must
     // compare lhsType against the supertype of rhsType with a matching base type.
     Type rhsTypeAsSuper = types.asSuper(rhsType, lhsType.tsym);
-    // This is impossible, considering the fact that standard Java subtyping succeeds before
-    // running NullAway
     if (rhsTypeAsSuper == null) {
-      throw new RuntimeException("Did not find supertype of " + rhsType + " matching " + lhsType);
+      // Surprisingly, this can in fact occur, in cases involving raw types.  See, e.g.,
+      // GenericsTests#issue1082 and https://github.com/uber/NullAway/pull/1086. Bail out.
+      return true;
     }
     // bail out of checking raw types for now
     if (rhsTypeAsSuper.isRaw()) {
diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
index 74a7ef481f..946b6963c4 100644
--- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
+++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java
@@ -2002,6 +2002,31 @@ public void issue1019() {
         .doTest();
   }
 
+  @Test
+  public void issue1082() {
+    makeHelper()
+        .addSourceLines(
+            "Main.java",
+            "package com.uber;",
+            "import java.util.Optional;",
+            "public class Main {",
+            "  public interface Factory<T> {",
+            "    T create();",
+            "  }",
+            "  public interface Expiry<K, V> {}",
+            "  static class Config<K, V> {",
+            "    Config<K, V> setFactory(Optional<Factory<? extends Expiry<K, V>>> factory) {",
+            "      return this;",
+            "    }",
+            "  }",
+            "  static void caller(Config config) {",
+            "    // checking that we don't crash",
+            "    config.setFactory(Optional.<Object>empty());",
+            "  }",
+            "}")
+        .doTest();
+  }
+
   private CompilationTestHelper makeHelper() {
     return makeTestHelperWithArgs(
         Arrays.asList(