Merge commit '2ce61bc7e5073fa7a02865fd0b4216719abf4c62' into dev-release
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json b/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json
index 57f7c3e..de5d525 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json
@@ -55,6 +55,7 @@
       "api_level_below_or_equal": 23,
       "rewrite_prefix": {
         "java.io.DesugarBufferedReader": "j$.io.DesugarBufferedReader",
+        "java.io.UncheckedIOException": "j$.io.UncheckedIOException",
         "java.util.DoubleSummaryStatistics": "j$.util.DoubleSummaryStatistics",
         "java.util.IntSummaryStatistics": "j$.util.IntSummaryStatistics",
         "java.util.LongSummaryStatistics": "j$.util.LongSummaryStatistics",
@@ -69,9 +70,6 @@
         "java.util.function.": "j$.util.function.",
         "java.util.stream.": "j$.util.stream."
       },
-      "maintain_prefix": [
-        "java.io.UncheckedIOException"
-      ],
       "emulate_interface": {
         "java.lang.Iterable": "j$.lang.Iterable",
         "java.util.Collection": "j$.util.Collection",
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index acbd677..7f74668 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -539,6 +539,7 @@
     assert !internal.isMinifying();
     assert !internal.passthroughDexCode;
     internal.passthroughDexCode = true;
+    assert internal.neverMergePrefixes.contains("j$.");
 
     // Assert some of R8 optimizations are disabled.
     assert !internal.inlinerOptions().enableInlining;
diff --git a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
index 7bfd947..3e33ca8 100644
--- a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
+++ b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
@@ -25,7 +25,6 @@
 
   static CodeToKeep createCodeToKeep(InternalOptions options, NamingLens namingLens) {
     if ((!namingLens.hasPrefixRewritingLogic()
-            && options.machineDesugaredLibrarySpecification.getMaintainType().isEmpty()
             && !options.machineDesugaredLibrarySpecification.hasEmulatedInterfaces())
         || options.isDesugaredLibraryCompilation()
         || options.testing.enableExperimentalDesugaredLibraryKeepRuleGenerator) {
@@ -68,7 +67,6 @@
 
     private boolean shouldKeep(DexType type) {
       return namingLens.prefixRewrittenType(type) != null
-          || options.machineDesugaredLibrarySpecification.getMaintainType().contains(type)
           || options.machineDesugaredLibrarySpecification.isCustomConversionRewrittenType(type)
           || options.machineDesugaredLibrarySpecification.isEmulatedInterfaceRewrittenType(type)
           // TODO(b/158632510): This should prefix match on DexString.
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 72cbe7d..c283797 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
@@ -28,7 +28,6 @@
       Nullability nullability,
       NullabilityVariants<ArrayTypeElement> variants) {
     super(nullability);
-    assert memberTypeLattice.isPrimitiveType() || memberTypeLattice.nullability().isMaybeNull();
     this.memberTypeLattice = memberTypeLattice;
     this.variants = variants;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
index 5499ffb..2eb550b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
@@ -48,7 +48,6 @@
   static final String WRAPPER_CONVERSION_EXCLUDING_KEY = "wrapper_conversion_excluding";
   static final String CUSTOM_CONVERSION_KEY = "custom_conversion";
   static final String REWRITE_PREFIX_KEY = "rewrite_prefix";
-  static final String MAINTAIN_PREFIX_KEY = "maintain_prefix";
   static final String RETARGET_METHOD_KEY = "retarget_method";
   static final String RETARGET_METHOD_EMULATED_DISPATCH_KEY =
       "retarget_method_with_emulated_dispatch";
@@ -236,11 +235,6 @@
         builder.putRewritePrefix(rewritePrefix.getKey(), rewritePrefix.getValue().getAsString());
       }
     }
-    if (jsonFlagSet.has(MAINTAIN_PREFIX_KEY)) {
-      for (JsonElement maintainPrefix : jsonFlagSet.get(MAINTAIN_PREFIX_KEY).getAsJsonArray()) {
-        builder.putMaintainPrefix(maintainPrefix.getAsString());
-      }
-    }
     if (jsonFlagSet.has(REWRITE_DERIVED_PREFIX_KEY)) {
       for (Map.Entry<String, JsonElement> prefixToMatch :
           jsonFlagSet.get(REWRITE_DERIVED_PREFIX_KEY).getAsJsonObject().entrySet()) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
index 8f4c435..9eb3ed7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
@@ -24,7 +24,6 @@
 public class HumanRewritingFlags {
 
   private final Map<String, String> rewritePrefix;
-  private final Set<String> maintainPrefix;
   private final Map<String, Map<String, String>> rewriteDerivedPrefix;
   private final Map<DexType, DexType> emulatedInterfaces;
   private final Map<DexMethod, DexType> retargetMethod;
@@ -38,7 +37,6 @@
 
   HumanRewritingFlags(
       Map<String, String> rewritePrefix,
-      Set<String> maintainPrefix,
       Map<String, Map<String, String>> rewriteDerivedPrefix,
       Map<DexType, DexType> emulateLibraryInterface,
       Map<DexMethod, DexType> retargetMethod,
@@ -50,7 +48,6 @@
       Map<DexType, Set<DexMethod>> wrapperConversion,
       Map<DexMethod, MethodAccessFlags> amendLibraryMethod) {
     this.rewritePrefix = rewritePrefix;
-    this.maintainPrefix = maintainPrefix;
     this.rewriteDerivedPrefix = rewriteDerivedPrefix;
     this.emulatedInterfaces = emulateLibraryInterface;
     this.retargetMethod = retargetMethod;
@@ -66,7 +63,6 @@
   public static HumanRewritingFlags empty() {
     return new HumanRewritingFlags(
         ImmutableMap.of(),
-        ImmutableSet.of(),
         ImmutableMap.of(),
         ImmutableMap.of(),
         ImmutableMap.of(),
@@ -88,7 +84,6 @@
         reporter,
         origin,
         rewritePrefix,
-        maintainPrefix,
         rewriteDerivedPrefix,
         emulatedInterfaces,
         retargetMethod,
@@ -105,10 +100,6 @@
     return rewritePrefix;
   }
 
-  public Set<String> getMaintainPrefix() {
-    return maintainPrefix;
-  }
-
   public Map<String, Map<String, String>> getRewriteDerivedPrefix() {
     return rewriteDerivedPrefix;
   }
@@ -162,7 +153,6 @@
     private final Origin origin;
 
     private final Map<String, String> rewritePrefix;
-    private final Set<String> maintainPrefix;
     private final Map<String, Map<String, String>> rewriteDerivedPrefix;
     private final Map<DexType, DexType> emulatedInterfaces;
     private final Map<DexMethod, DexType> retargetMethod;
@@ -179,7 +169,6 @@
           reporter,
           origin,
           new HashMap<>(),
-          Sets.newIdentityHashSet(),
           new HashMap<>(),
           new IdentityHashMap<>(),
           new IdentityHashMap<>(),
@@ -196,7 +185,6 @@
         Reporter reporter,
         Origin origin,
         Map<String, String> rewritePrefix,
-        Set<String> maintainPrefix,
         Map<String, Map<String, String>> rewriteDerivedPrefix,
         Map<DexType, DexType> emulateLibraryInterface,
         Map<DexMethod, DexType> retargetMethod,
@@ -210,7 +198,6 @@
       this.reporter = reporter;
       this.origin = origin;
       this.rewritePrefix = new HashMap<>(rewritePrefix);
-      this.maintainPrefix = Sets.newHashSet(maintainPrefix);
       this.rewriteDerivedPrefix = new HashMap<>(rewriteDerivedPrefix);
       this.emulatedInterfaces = new IdentityHashMap<>(emulateLibraryInterface);
       this.retargetMethod = new IdentityHashMap<>(retargetMethod);
@@ -250,11 +237,6 @@
       return this;
     }
 
-    public Builder putMaintainPrefix(String prefix) {
-      maintainPrefix.add(prefix);
-      return this;
-    }
-
     public Builder putRewriteDerivedPrefix(
         String prefixToMatch, String prefixToRewrite, String rewrittenPrefix) {
       Map<String, String> map =
@@ -340,7 +322,6 @@
       validate();
       return new HumanRewritingFlags(
           ImmutableMap.copyOf(rewritePrefix),
-          ImmutableSet.copyOf(maintainPrefix),
           ImmutableMap.copyOf(rewriteDerivedPrefix),
           ImmutableMap.copyOf(emulatedInterfaces),
           ImmutableMap.copyOf(retargetMethod),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
index 735d4f0..1f52b3d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
@@ -82,10 +82,6 @@
     return rewritingFlags.getRewriteType();
   }
 
-  public Set<DexType> getMaintainType() {
-    return rewritingFlags.getMaintainType();
-  }
-
   public Map<DexType, DexType> getRewriteDerivedTypeOnly() {
     return rewritingFlags.getRewriteDerivedTypeOnly();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
index 0f1aef3..00a4747 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
@@ -25,7 +25,6 @@
 
   MachineRewritingFlags(
       Map<DexType, DexType> rewriteType,
-      Set<DexType> maintainType,
       Map<DexType, DexType> rewriteDerivedTypeOnly,
       Map<DexMethod, DexMethod> staticRetarget,
       Map<DexMethod, DexMethod> nonEmulatedVirtualRetarget,
@@ -38,7 +37,6 @@
       Map<DexType, CustomConversionDescriptor> customConversions,
       Map<DexMethod, MethodAccessFlags> amendLibraryMethods) {
     this.rewriteType = rewriteType;
-    this.maintainType = maintainType;
     this.rewriteDerivedTypeOnly = rewriteDerivedTypeOnly;
     this.staticRetarget = staticRetarget;
     this.nonEmulatedVirtualRetarget = nonEmulatedVirtualRetarget;
@@ -55,8 +53,6 @@
 
   // Rewrites all the references to the keys as well as synthetic types derived from any key.
   private final Map<DexType, DexType> rewriteType;
-  // Maintains the references in the desugared library dex file.
-  private final Set<DexType> maintainType;
   // Rewrites only synthetic types derived from any key.
   private final Map<DexType, DexType> rewriteDerivedTypeOnly;
 
@@ -92,10 +88,6 @@
     return rewriteType;
   }
 
-  public Set<DexType> getMaintainType() {
-    return maintainType;
-  }
-
   public Map<DexType, DexType> getRewriteDerivedTypeOnly() {
     return rewriteDerivedTypeOnly;
   }
@@ -182,7 +174,6 @@
     Builder() {}
 
     private final Map<DexType, DexType> rewriteType = new IdentityHashMap<>();
-    private final ImmutableSet.Builder<DexType> maintainType = ImmutableSet.builder();
     private final Map<DexType, DexType> rewriteDerivedTypeOnly = new IdentityHashMap<>();
     private final ImmutableMap.Builder<DexMethod, DexMethod> staticRetarget =
         ImmutableMap.builder();
@@ -210,11 +201,6 @@
       rewriteType.put(src, target);
     }
 
-    public void maintainType(DexType type) {
-      assert type != null;
-      maintainType.add(type);
-    }
-
     public void rewriteDerivedTypeOnly(DexType src, DexType target) {
       rewriteDerivedTypeOnly.put(src, target);
     }
@@ -266,7 +252,6 @@
     public MachineRewritingFlags build() {
       return new MachineRewritingFlags(
           rewriteType,
-          maintainType.build(),
           rewriteDerivedTypeOnly,
           staticRetarget.build(),
           nonEmulatedVirtualRetarget.build(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
index 78fc59f..87c03e3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
@@ -13,7 +13,6 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import java.util.Map;
 import java.util.Set;
@@ -26,7 +25,6 @@
   private final String synthesizedPrefix;
   private final boolean libraryCompilation;
   private final Map<DexString, DexString> descriptorPrefix;
-  private final Set<DexString> descriptorMaintainPrefix;
   private final Map<DexString, Map<DexString, DexString>> descriptorDifferentPrefix;
   private final Set<DexString> usedPrefix = Sets.newIdentityHashSet();
 
@@ -40,7 +38,6 @@
     this.synthesizedPrefix = humanSpec.getSynthesizedLibraryClassesPackagePrefix();
     this.libraryCompilation = humanSpec.isLibraryCompilation();
     this.descriptorPrefix = convertRewritePrefix(rewritingFlags.getRewritePrefix());
-    this.descriptorMaintainPrefix = convertMaintainPrefix(rewritingFlags.getMaintainPrefix());
     this.descriptorDifferentPrefix =
         convertRewriteDifferentPrefix(rewritingFlags.getRewriteDerivedPrefix());
   }
@@ -59,7 +56,6 @@
   private void warnIfUnusedPrefix(BiConsumer<String, Set<DexString>> warnConsumer) {
     Set<DexString> prefixes = Sets.newIdentityHashSet();
     prefixes.addAll(descriptorPrefix.keySet());
-    prefixes.addAll(descriptorMaintainPrefix);
     prefixes.addAll(descriptorDifferentPrefix.keySet());
     prefixes.removeAll(usedPrefix);
     warnConsumer.accept("The following prefixes do not match any type: ", prefixes);
@@ -103,7 +99,6 @@
 
   private void registerClassType(DexType type) {
     registerType(type);
-    registerMaintainType(type);
     registerDifferentType(type);
   }
 
@@ -114,15 +109,6 @@
     }
   }
 
-  private void registerMaintainType(DexType type) {
-    DexString prefix = prefixMatching(type, descriptorMaintainPrefix);
-    if (prefix == null) {
-      return;
-    }
-    builder.maintainType(type);
-    usedPrefix.add(prefix);
-  }
-
   private void registerDifferentType(DexType type) {
     DexString prefix = prefixMatching(type, descriptorDifferentPrefix.keySet());
     if (prefix == null) {
@@ -174,14 +160,6 @@
     return mapBuilder.build();
   }
 
-  private ImmutableSet<DexString> convertMaintainPrefix(Set<String> maintainPrefix) {
-    ImmutableSet.Builder<DexString> builder = ImmutableSet.builder();
-    for (String prefix : maintainPrefix) {
-      builder.add(toDescriptorPrefix(prefix));
-    }
-    return builder.build();
-  }
-
   private ImmutableMap<DexString, DexString> convertRewritePrefix(
       Map<String, String> rewritePrefix) {
     ImmutableMap.Builder<DexString, DexString> mapBuilder = ImmutableMap.builder();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index 3919202..dc739bb 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -98,13 +98,6 @@
     if (isEmulatedInterface(clazz.type)) {
       return true;
     }
-    if (appView
-        .options()
-        .machineDesugaredLibrarySpecification
-        .getMaintainType()
-        .contains(clazz.type)) {
-      return true;
-    }
     return appView.typeRewriter.hasRewrittenType(clazz.type, appView);
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index a9a33cb..2ae7d7d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -713,9 +713,7 @@
       DexClass clazz, DexMethod invokedMethod, ProgramMethod context) {
     DexClassAndMethod superTarget =
         appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context);
-    if (clazz.isInterface()
-        && helper.isInDesugaredLibrary(clazz)
-        && !helper.isEmulatedInterface(clazz.type)) {
+    if (clazz.isInterface() && appView.typeRewriter.hasRewrittenType(clazz.type, appView)) {
       if (superTarget != null && superTarget.getDefinition().isDefaultMethod()) {
         DexClass holder = superTarget.getHolder();
         if (holder.isLibraryClass() && holder.isInterface()) {
diff --git a/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java b/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java
index d462818..46e77e8 100644
--- a/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.TypeRewriter;
 import com.android.tools.r8.utils.InternalOptions;
+import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.IdentityHashMap;
 import java.util.List;
@@ -21,24 +22,25 @@
 public class L8TreePruner {
 
   private final InternalOptions options;
+  private final Set<DexType> emulatedInterfaces = Sets.newIdentityHashSet();
+  private final Set<DexType> backports = Sets.newIdentityHashSet();
   private final List<DexType> pruned = new ArrayList<>();
 
   public L8TreePruner(InternalOptions options) {
     this.options = options;
+    backports.addAll(options.machineDesugaredLibrarySpecification.getLegacyBackport().keySet());
+    emulatedInterfaces.addAll(
+        options.machineDesugaredLibrarySpecification.getEmulatedInterfaces().keySet());
   }
 
   public DexApplication prune(DexApplication app, TypeRewriter typeRewriter) {
-    Set<DexType> maintainType = options.machineDesugaredLibrarySpecification.getMaintainType();
-    Set<DexType> emulatedInterfaces =
-        options.machineDesugaredLibrarySpecification.getEmulatedInterfaces().keySet();
     Map<DexType, DexProgramClass> typeMap = new IdentityHashMap<>();
     List<DexProgramClass> toKeep = new ArrayList<>();
     boolean pruneNestMember = false;
     for (DexProgramClass aClass : app.classes()) {
       typeMap.put(aClass.type, aClass);
       if (typeRewriter.hasRewrittenType(aClass.type, null)
-          || emulatedInterfaces.contains(aClass.type)
-          || maintainType.contains(aClass.type)) {
+          || emulatedInterfaces.contains(aClass.type)) {
         toKeep.add(aClass);
       } else {
         pruneNestMember |= aClass.isInANest();
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 133f721..50c315a 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -274,7 +274,6 @@
 
   // Flag to toggle if the prefix based merge restriction should be enforced.
   public boolean enableNeverMergePrefixes = true;
-  // TODO(b/227277105): Control merging with desugared library and maintain prefix.
   public Set<String> neverMergePrefixes = ImmutableSet.of("j$.");
 
   public boolean classpathInterfacesMayHaveStaticInitialization = false;
@@ -938,10 +937,6 @@
     }
     timing.begin("Load machine specification");
     loadMachineDesugaredLibrarySpecification.accept(timing, app);
-    if (!machineDesugaredLibrarySpecification.getMaintainType().isEmpty()) {
-      // TODO(b/227277105): Control merging with desugared library and maintain prefix.
-      neverMergePrefixes = ImmutableSet.of();
-    }
     timing.end();
   }
 
diff --git a/src/test/java/com/android/tools/r8/L8TestBuilder.java b/src/test/java/com/android/tools/r8/L8TestBuilder.java
index 2ff60ba..7a42ab1 100644
--- a/src/test/java/com/android/tools/r8/L8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/L8TestBuilder.java
@@ -184,10 +184,7 @@
         .inspect(
             inspector ->
                 inspector.forAllClasses(
-                    clazz ->
-                        assertTrue(
-                            clazz.getFinalName().startsWith("j$.")
-                                || clazz.getFinalName().startsWith("java."))));
+                    clazz -> assertTrue(clazz.getFinalName().startsWith("j$."))));
   }
 
   private Collection<Path> getProgramFiles() {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
index 93ea904..f79b585 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
@@ -51,7 +51,13 @@
   }
 
   private String expectedOutput() {
-    return StringUtils.lines("Hello", "Larry", "Page", "Caught java.io.UncheckedIOException");
+    return StringUtils.lines(
+        "Hello",
+        "Larry",
+        "Page",
+        parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N)
+            ? "Caught java.io.UncheckedIOException"
+            : "Caught j$.io.UncheckedIOException");
   }
 
   DesugaredLibrarySpecification configurationAlternative3(
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 4f15b2d..3e83719 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
@@ -4,6 +4,8 @@
 package com.android.tools.r8.ir.analysis.type;
 
 import static com.android.tools.r8.ir.analysis.type.ClassTypeElement.computeLeastUpperBoundOfInterfaces;
+import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
+import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
 import static com.android.tools.r8.ir.analysis.type.TypeElement.fromDexType;
 import static com.android.tools.r8.ir.analysis.type.TypeElement.getBottom;
 import static com.android.tools.r8.ir.analysis.type.TypeElement.getTop;
@@ -88,10 +90,25 @@
     return TypeElement.fromDexType(type, nullability, appView);
   }
 
+  private ClassTypeElement element(DexType type, Nullability nullability, DexType... interfaces) {
+    assert type.isClassType();
+    InterfaceCollection.Builder interfaceCollectionBuilder = InterfaceCollection.builder();
+    Arrays.asList(interfaces).forEach(interfaceCollectionBuilder::addKnownInterface);
+    return ClassTypeElement.create(type, nullability, appView, interfaceCollectionBuilder.build());
+  }
+
   private ArrayTypeElement array(int nesting, DexType base) {
     return (ArrayTypeElement) element(factory.createArrayType(nesting, base));
   }
 
+  private ArrayTypeElement array(TypeElement baseType) {
+    return array(baseType, maybeNull());
+  }
+
+  private ArrayTypeElement array(TypeElement baseType, Nullability nullability) {
+    return ArrayTypeElement.create(baseType, nullability);
+  }
+
   private TypeElement join(TypeElement... elements) {
     assertTrue(elements.length > 1);
     return TypeElement.join(Arrays.asList(elements), appView);
@@ -374,63 +391,59 @@
   @Test
   public void joinDistinctTypesPrimitiveArrays() {
     assertEquals(
-        array(2, factory.objectType),
-        join(
-            array(3, factory.intType),
-            array(3, factory.floatType)));
+        array(
+            array(
+                element(
+                    factory.objectType,
+                    definitelyNotNull(),
+                    factory.cloneableType,
+                    factory.serializableType))),
+        join(array(3, factory.intType), array(3, factory.floatType)));
   }
 
   @Test
   public void joinDistinctTypesNestingOnePrimitiveArrays() {
     assertEquals(
-        element(factory.objectType),
-        join(
-            array(1, factory.intType),
-            array(1, factory.floatType)));
+        element(factory.objectType, maybeNull(), factory.cloneableType, factory.serializableType),
+        join(array(1, factory.intType), array(1, factory.floatType)));
     assertEquals(
-        element(factory.objectType),
-        join(
-            array(1, factory.longType),
-            array(1, factory.intType)));
+        element(factory.objectType, maybeNull(), factory.cloneableType, factory.serializableType),
+        join(array(1, factory.longType), array(1, factory.intType)));
 
     // Test primitive types smaller than int.
     assertEquals(
-        element(factory.objectType),
-        join(
-            array(1, factory.intType),
-            array(1, factory.byteType)));
+        element(factory.objectType, maybeNull(), factory.cloneableType, factory.serializableType),
+        join(array(1, factory.intType), array(1, factory.byteType)));
     assertEquals(
-        element(factory.objectType),
-        join(
-            array(1, factory.charType),
-            array(1, factory.shortType)));
+        element(factory.objectType, maybeNull(), factory.cloneableType, factory.serializableType),
+        join(array(1, factory.charType), array(1, factory.shortType)));
   }
 
   @Test
   public void joinDistinctTypesNestingOneRightPrimitiveArrays() {
     assertEquals(
-        element(factory.objectType),
-        join(
-            array(5, factory.intType),
-            array(1, factory.floatType)));
+        element(factory.objectType, maybeNull(), factory.cloneableType, factory.serializableType),
+        join(array(5, factory.intType), array(1, factory.floatType)));
   }
 
   @Test
   public void joinDistinctTypesNestingOneLeftPrimitiveArrays() {
     assertEquals(
-        element(factory.objectType),
-        join(
-            array(1, factory.intType),
-            array(5, factory.floatType)));
+        element(factory.objectType, maybeNull(), factory.cloneableType, factory.serializableType),
+        join(array(1, factory.intType), array(5, factory.floatType)));
   }
 
   @Test
   public void joinDistinctNestingPrimitiveArrays() {
     assertEquals(
-        array(2, factory.objectType),
-        join(
-            array(3, factory.intType),
-            array(4, factory.intType)));
+        array(
+            array(
+                element(
+                    factory.objectType,
+                    maybeNull(),
+                    factory.cloneableType,
+                    factory.serializableType))),
+        join(array(3, factory.intType), array(4, factory.intType)));
   }
 
   @Test
@@ -519,10 +532,10 @@
     assertTrue(
         lessThanOrEqualUpToNullability(
             element(factory.objectType, Nullability.maybeNull()),
-            element(factory.objectType, Nullability.definitelyNotNull())));
+            element(factory.objectType, definitelyNotNull())));
     assertTrue(
         lessThanOrEqualUpToNullability(
-            element(factory.objectType, Nullability.definitelyNotNull()),
+            element(factory.objectType, definitelyNotNull()),
             element(factory.objectType, Nullability.maybeNull())));
     assertFalse(
         lessThanOrEqualUpToNullability(array(3, factory.stringType), array(4, factory.stringType)));
@@ -535,7 +548,7 @@
   @Test
   public void testSelfOrderWithoutSubtypingInfo() {
     DexType type = factory.createType("Lmy/Type;");
-    TypeElement nonNullType = fromDexType(type, Nullability.definitelyNotNull(), appView);
+    TypeElement nonNullType = fromDexType(type, definitelyNotNull(), appView);
     ReferenceTypeElement nullableType =
         nonNullType.asReferenceType().getOrCreateVariant(Nullability.maybeNull());
     assertTrue(strictlyLessThan(nonNullType, nullableType));