Handle collision with defaultEnumUnboxingUtility in field synthesis

Change-Id: I989be9e3a71233c9be7f6b52a3eafbf5c91e933e
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
index 320e8ce..5a8ae19 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
@@ -65,7 +65,7 @@
   }
 
   public static class Builder {
-    private DexType defaultEnumUnboxingUtility;
+    private DexProgramClass defaultEnumUnboxingUtility;
     private Map<DexType, DexType> relocationMap = new IdentityHashMap<>();
     private final AppView<?> appView;
 
@@ -99,7 +99,7 @@
 
     public UnboxedEnumMemberRelocator build() {
       return new UnboxedEnumMemberRelocator(
-          defaultEnumUnboxingUtility, ImmutableMap.copyOf(relocationMap));
+          defaultEnumUnboxingUtility.getType(), ImmutableMap.copyOf(relocationMap));
     }
 
     private void synthesizeRelocationMap(
@@ -109,20 +109,22 @@
         FieldAccessInfoCollectionModifier.Builder fieldAccessInfoCollectionModifierBuilder) {
       for (ProgramPackage programPackage : enumsToUnboxWithPackageRequirement) {
         Set<DexProgramClass> enumsToUnboxInPackage = programPackage.classesInPackage();
-        DexType utilityType =
+        DexProgramClass enumUtilityClass =
             synthesizeUtilityClass(
                 contexts,
                 enumsToUnboxInPackage,
                 appBuilder,
                 fieldAccessInfoCollectionModifierBuilder);
-        for (DexProgramClass enumToUnbox : enumsToUnboxInPackage) {
-          assert !relocationMap.containsKey(enumToUnbox.type);
-          relocationMap.put(enumToUnbox.type, utilityType);
+        if (enumUtilityClass != defaultEnumUnboxingUtility) {
+          for (DexProgramClass enumToUnbox : enumsToUnboxInPackage) {
+            assert !relocationMap.containsKey(enumToUnbox.type);
+            relocationMap.put(enumToUnbox.type, enumUtilityClass.getType());
+          }
         }
       }
     }
 
-    private DexType synthesizeUtilityClass(
+    private DexProgramClass synthesizeUtilityClass(
         Set<DexProgramClass> contexts,
         Set<DexProgramClass> relocatedEnums,
         DirectMappedDexApplication.Builder appBuilder,
@@ -133,13 +135,8 @@
       String descriptorPrefix = descriptorString.substring(0, descriptorString.length() - 1);
       String syntheticClassDescriptor = descriptorPrefix + ENUM_UNBOXING_UTILITY_CLASS_SUFFIX + ";";
       DexType type = appView.dexItemFactory().createType(syntheticClassDescriptor);
-      // The defaultEnumUnboxingUtility depends on all unboxable enums, and other synthetic types
-      // depend on a subset of the unboxable enums, the deterministicContextType can therefore
-      // be found twice, and in that case the same utility class can be used for both.
-      if (type == defaultEnumUnboxingUtility) {
-        return defaultEnumUnboxingUtility;
-      }
-      assert appView.appInfo().definitionForWithoutExistenceAssert(type) == null;
+
+      // Required fields.
       List<DexEncodedField> staticFields = new ArrayList<>(relocatedEnums.size());
       for (DexProgramClass relocatedEnum : relocatedEnums) {
         DexField reference =
@@ -151,6 +148,15 @@
             .recordFieldWriteInUnknownContext(reference);
       }
       staticFields.sort(Comparator.comparing(DexEncodedField::getReference));
+
+      // The defaultEnumUnboxingUtility depends on all unboxable enums, and other synthetic types
+      // depend on a subset of the unboxable enums, the deterministicContextType can therefore
+      // be found twice, and in that case the same utility class can be used for both.
+      if (defaultEnumUnboxingUtility != null && type == defaultEnumUnboxingUtility.getType()) {
+        defaultEnumUnboxingUtility.appendStaticFields(staticFields);
+        return defaultEnumUnboxingUtility;
+      }
+      assert appView.appInfo().definitionForWithoutExistenceAssert(type) == null;
       DexProgramClass syntheticClass =
           new DexProgramClass(
               type,
@@ -178,7 +184,7 @@
           .appInfo()
           .addSynthesizedClass(
               syntheticClass, appView.appInfo().getMainDexClasses().containsAnyOf(contexts));
-      return syntheticClass.type;
+      return syntheticClass;
     }
 
     private DexType findDeterministicContextType(Set<DexProgramClass> contexts) {