Fix and regression test for lambda with undefined interface.

Bug: b/232379893
Bug: b/233868787
Change-Id: I845f13b92121f2ae1eba470246ded606464d5bf6
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 09df4b5..39901f4 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3599,10 +3599,31 @@
       }
     }
 
+    BiConsumer<LambdaClass, ProgramMethod> lambdaCallback = this::recordLambdaSynthesizingContext;
+    // TODO(b/233868787): If a lambda implements unknown interfaces its methods won't be live and if
+    //  the tree-pruner is disabled they won't be removed. Workaround this by making them live.
+    if (!options.isShrinking()) {
+      lambdaCallback =
+          lambdaCallback.andThen(
+              (clazz, context) -> {
+                for (DexType itf : clazz.getLambdaProgramClass().getInterfaces()) {
+                  if (definitionFor(itf, context) == null) {
+                    for (ProgramMethod method :
+                        clazz.getLambdaProgramClass().virtualProgramMethods()) {
+                      synchronized (additions) {
+                        additions.addLiveMethod(method);
+                      }
+                    }
+                    break;
+                  }
+                }
+              });
+    }
+
     R8CfInstructionDesugaringEventConsumer eventConsumer =
         CfInstructionDesugaringEventConsumer.createForR8(
             appView,
-            this::recordLambdaSynthesizingContext,
+            lambdaCallback,
             this::recordConstantDynamicSynthesizingContext,
             this::recordTwrCloseResourceMethodSynthesizingContext,
             additions,
diff --git a/src/test/java/com/android/tools/r8/regress/UndefinedLambdaInterfaceRegress232379893.java b/src/test/java/com/android/tools/r8/regress/UndefinedLambdaInterfaceRegress232379893.java
new file mode 100644
index 0000000..b27e96a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/regress/UndefinedLambdaInterfaceRegress232379893.java
@@ -0,0 +1,62 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.regress;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.StringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class UndefinedLambdaInterfaceRegress232379893 extends TestBase {
+
+  static final String EXPECTED = StringUtils.lines("Hello, world");
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().withAllApiLevels().build();
+  }
+
+  public UndefinedLambdaInterfaceRegress232379893(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClasses(TestClass.class)
+        .addProgramClassesAndInnerClasses(UserOfUndefinedInterface.class)
+        .addKeepMainRule(TestClass.class)
+        .addDontWarn(UndefinedInterface.class)
+        .addDontShrink()
+        .setMinApi(parameters.getApiLevel())
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
+
+  interface UndefinedInterface {
+    void foo();
+  }
+
+  static class UserOfUndefinedInterface {
+    public static void bar(UndefinedInterface i) {
+      throw new RuntimeException("unused method");
+    }
+  }
+
+  static class TestClass {
+    public static void main(String[] args) {
+      if (System.nanoTime() < 0) {
+        UserOfUndefinedInterface.bar(() -> System.out.println("unused lambda"));
+      } else {
+        System.out.println("Hello, world");
+      }
+    }
+  }
+}