Fix imprecision in join of array type elements

Fixes: b/236931189
Change-Id: I68564eb8d514e05bfb526c5913f660fdf8911c96
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeElement.java
index 6b77171..a2acb83 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeElement.java
@@ -184,22 +184,23 @@
       // Return null indicating the join is the same as the member to avoid object allocation.
       return null;
     }
-    if (aMember.isArrayType() && bMember.isArrayType()) {
-      TypeElement aMemberMember = aMember.asArrayType().getMemberType();
-      TypeElement bMemberMember = bMember.asArrayType().getMemberType();
-      TypeElement join =
-          joinMember(
-              aMemberMember,
-              bMemberMember,
-              appView,
-              aMember.nullability().join(bMember.nullability()));
-      return join == null ? null : ArrayTypeElement.create(join, nullability);
-    }
-    if (aMember.isClassType() && bMember.isClassType()) {
-      ReferenceTypeElement join = aMember.asClassType().join(bMember.asClassType(), appView);
+    if (aMember.isReferenceType() && bMember.isReferenceType()) {
+      if (aMember.isArrayType() && bMember.isArrayType()) {
+        TypeElement aMemberMember = aMember.asArrayType().getMemberType();
+        TypeElement bMemberMember = bMember.asArrayType().getMemberType();
+        TypeElement join =
+            joinMember(
+                aMemberMember,
+                bMemberMember,
+                appView,
+                aMember.nullability().join(bMember.nullability()));
+        return join == null ? null : ArrayTypeElement.create(join, nullability);
+      }
+      ReferenceTypeElement join =
+          aMember.asReferenceType().join(bMember.asReferenceType(), appView);
       return ArrayTypeElement.create(join, nullability);
-    }
-    if (aMember.isPrimitiveType() || bMember.isPrimitiveType()) {
+    } else {
+      assert aMember.isPrimitiveType() || bMember.isPrimitiveType();
       if (appView.enableWholeProgramOptimizations()) {
         assert appView.hasClassHierarchy();
         DexItemFactory dexItemFactory = appView.dexItemFactory();
@@ -216,6 +217,5 @@
       }
       return objectClassType(appView, nullability);
     }
-    return objectArrayType(appView, nullability);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeLatticeTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeLatticeTest.java
index 4f8c88c..3bf42fa 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeLatticeTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeLatticeTest.java
@@ -449,10 +449,8 @@
   @Test
   public void joinPrimitiveAndClassArrays() {
     assertEquals(
-        array(3, factory.objectType),
-        join(
-            array(4, factory.intType),
-            array(3, factory.stringType)));
+        array(array(array(element(factory.objectType, maybeNull(), factory.serializableType)))),
+        join(array(4, factory.intType), array(3, factory.stringType)));
   }
 
   @Test
@@ -476,10 +474,8 @@
   @Test
   public void joinDistinctNestingClassArrays() {
     assertEquals(
-        array(3, factory.objectType),
-        join(
-            array(3, factory.stringType),
-            array(4, factory.stringType)));
+        array(array(array(element(factory.objectType, maybeNull(), factory.serializableType)))),
+        join(array(3, factory.stringType), array(4, factory.stringType)));
   }
 
   @Test