Ensure that we can merge desugared java8 classes

We do create a single class for each method, but when merging we did
not take into account that we allow multiple instances of these.

Bug: 123242448
Change-Id: If4ec57e9d3172c6fe6fe8facaf6efb7916e1aa49
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
index c0a7569..9e2e9ab 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
@@ -84,6 +84,10 @@
     return null;
   }
 
+  public static boolean hasJava8MethodRewritePrefix(DexType clazz) {
+    return clazz.descriptor.toString().startsWith(UTILITY_CLASS_DESCRIPTOR_PREFIX);
+  }
+
   public void synthesizeUtilityClass(Builder<?> builder, InternalOptions options) {
     if (holders.isEmpty()) {
       return;
diff --git a/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java b/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
index 3b2b878..1cf61c0 100644
--- a/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
+++ b/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
+import com.android.tools.r8.ir.desugar.Java8MethodRewriter;
 import com.android.tools.r8.ir.desugar.LambdaRewriter;
 import com.android.tools.r8.ir.desugar.TwrCloseResourceRewriter;
 import java.util.List;
@@ -68,6 +69,7 @@
 
   private static boolean assumeClassesAreEqual(DexProgramClass a) {
     return LambdaRewriter.hasLambdaClassPrefix(a.type)
+        || Java8MethodRewriter.hasJava8MethodRewritePrefix(a.type)
         || InterfaceMethodRewriter.hasDispatchClassSuffix(a.type)
         || a.type.descriptor.toString().equals(TwrCloseResourceRewriter.UTILITY_CLASS_DESCRIPTOR);
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java b/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
index f94d5a5..053ac5c 100644
--- a/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
@@ -4,7 +4,10 @@
 
 package com.android.tools.r8.desugar;
 
+import com.android.tools.r8.D8TestCompileResult;
 import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.nio.file.Path;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -26,6 +29,62 @@
         .assertSuccessWithOutput(expectedOutput);
   }
 
+  @Test
+  public void testD8Merge() throws Exception {
+    String jvmOutput = testForJvm()
+        .addTestClasspath()
+        .run(MergeRun.class).getStdOut();
+
+    // See b/123242448
+    Path zip1 = temp.newFile("first.zip").toPath();
+    Path zip2 = temp.newFile("second.zip").toPath();
+    Path zip3 = temp.newFile("third.zip").toPath();
+
+    D8TestCompileResult result1 =
+        testForD8()
+            .setMinApi(AndroidApiLevel.L)
+            .addProgramClasses(MergeRun.class, MergeInputB.class)
+            .compile()
+            .writeToZip(zip1);
+    D8TestCompileResult result2 =
+        testForD8()
+            .setMinApi(AndroidApiLevel.L)
+            .addProgramClasses(MergeInputA.class)
+            .compile()
+            .writeToZip(zip2);
+
+    testForD8()
+        .addProgramFiles(zip1, zip2)
+        .setMinApi(AndroidApiLevel.L)
+        .compile()
+        .run(MergeRun.class)
+        .assertSuccessWithOutput(jvmOutput);
+  }
+
+
+  static class MergeInputA {
+    public void foo() {
+      System.out.println(Integer.hashCode(42));
+      System.out.println(Double.hashCode(42.0));
+    }
+  }
+
+  static class MergeInputB {
+    public void foo() {
+      System.out.println(Integer.hashCode(43));
+      System.out.println(Double.hashCode(43.0));
+    }
+  }
+
+  static class MergeRun {
+    public static void main(String[] args) {
+      MergeInputA a = new MergeInputA();
+      MergeInputB b = new MergeInputB();
+      a.foo();
+      b.foo();
+    }
+  }
+
   static class Java8Methods {
     public static void main(String[] args) {
       byte[] aBytes = new byte[]{42, 1, -1, Byte.MAX_VALUE, Byte.MIN_VALUE};