Desugar records again for Android U (API level 34)

Art had a bug in native record support in the initial release of
Android U.

This will be fixed with Art mainline updates, but turning record
desugaring on again for API level 34 to avoid hitting issues on
Android U where mainline updates are not been applied.

Also removed the predicate canUseNativeRecords and replaced with
isRecordsDesugaredForD8 and isRecordsDesugaredForR8. These two
together with runtimeWithRecordsSupport are now used in all record
tests.

Bug: b/312443509
Change-Id: I111e9779b657492583cd7b9eb60788d8ec6d198e
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 d62c022..b0d3c73 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -468,7 +468,7 @@
   public boolean createSingletonsForStatelessLambdas =
       System.getProperty("com.android.tools.r8.createSingletonsForStatelessLambdas") != null;
 
-  // TODO(b/293591931): Remove this flag.
+  // TODO(b/293591931): Remove this flag when records are stable in Platform
   //  Flag to allow record annotations in DEX. See b/231930852 for context.
   private final boolean emitRecordAnnotationsInDex =
       System.getProperty("com.android.tools.r8.emitRecordAnnotationsInDex") != null;
@@ -2612,7 +2612,7 @@
   }
 
   public boolean canUseRecords() {
-    return hasFeaturePresentFrom(AndroidApiLevel.U) || emitRecordAnnotationsInDex;
+    return hasFeaturePresentFrom(null) || emitRecordAnnotationsInDex;
   }
 
   public boolean canUseSealedClasses() {
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index f869fd3..06eebe6 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -1738,8 +1738,25 @@
     return AndroidApiLevel.O;
   }
 
-  public static boolean canUseNativeRecords(TestParameters parameters) {
-    return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U);
+  public static AndroidApiLevel apiLevelWithRecordSupport() {
+    // TODO(b/293591931): Return something when records are stable in Platform (expecting Android
+    // V).
+    throw new Unreachable();
+  }
+
+  public static boolean isRecordsDesugaredForD8(TestParameters parameters) {
+    assert parameters.getApiLevel() != null;
+    // TODO(b/293591931): Return true for some API level when records are stable in Platform
+    //  (expecting Android V) using TestBase.apiLevelWithRecordSupport().
+    return true;
+  }
+
+  public static boolean isRecordsDesugaredForR8(TestParameters parameters) {
+    assert parameters.getApiLevel() != null;
+    // TODO(b/293591931): Also return true for some API level when records are stable in Platform
+    //  (expecting Android V) using TestBase.apiLevelWithRecordSupport(). Note that R8 with class
+    //  file output never performs desugaring.
+    return !parameters.getRuntime().isCf();
   }
 
   public static boolean canUseJavaUtilObjects(TestParameters parameters) {
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 2bd6d08..dffdc18 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -354,6 +354,7 @@
       }
 
       public boolean hasRecordsSupport() {
+        // Records support is present from Android U.
         return isNewerThanOrEqual(V14_0_0);
       }
 
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
index c2846c5..5c08537 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordAnnotationTest.java
@@ -59,15 +59,14 @@
         .compile()
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            canUseNativeRecords(parameters),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_NATIVE_RECORD),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_DESUGARED_RECORD));
+            isRecordsDesugaredForD8(parameters),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_DESUGARED_RECORD),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_NATIVE_RECORD));
   }
 
   @Test
   public void testR8() throws Exception {
     parameters.assumeR8TestParameters();
-    boolean willDesugarRecords = parameters.isDexRuntime() && !canUseNativeRecords(parameters);
     testForR8(parameters.getBackend())
         .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
         .addProgramClassFileData(PROGRAM_DATA)
@@ -77,13 +76,15 @@
         .addKeepRules("-keep class records.EmptyRecordAnnotation$Empty")
         .addKeepMainRule(MAIN_TYPE)
         // This is used to avoid renaming com.android.tools.r8.RecordTag.
-        .applyIf(willDesugarRecords, b -> b.addKeepRules("-keep class java.lang.Record"))
+        .applyIf(
+            isRecordsDesugaredForR8(parameters),
+            b -> b.addKeepRules("-keep class java.lang.Record"))
         .compile()
         .applyIf(parameters.isCfRuntime(), r -> r.inspect(RecordTestUtils::assertRecordsAreRecords))
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            !willDesugarRecords,
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_NATIVE_RECORD),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_DESUGARED_RECORD));
+            isRecordsDesugaredForR8(parameters),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_DESUGARED_RECORD),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_NATIVE_RECORD));
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordBlogTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordBlogTest.java
index 0fcb6da..05fdb8d 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordBlogTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordBlogTest.java
@@ -83,9 +83,10 @@
         .setMinApi(parameters)
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(ClassNotFoundException.class),
-            r -> r.assertSuccessWithOutput(computeOutput(REFERENCE_OUTPUT_FORMAT)));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(computeOutput(REFERENCE_OUTPUT_FORMAT)),
+            r -> r.assertFailureWithErrorThatThrows(ClassNotFoundException.class));
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordComponentAnnotationsTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordComponentAnnotationsTest.java
index 8ded32a..d2c05af 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordComponentAnnotationsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordComponentAnnotationsTest.java
@@ -16,8 +16,6 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.TestShrinkerBuilder;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.StringUtils;
@@ -36,7 +34,7 @@
   private static final String RECORD_NAME = "RecordWithAnnotations";
   private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
   private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
-  private static final String JVM_EXPECTED_RESULT =
+  private static final String JVM_UNTIL_20_EXPECTED_RESULT =
       StringUtils.lines(
           "Jane Doe",
           "42",
@@ -63,6 +61,9 @@
           "2",
           "@records.RecordWithAnnotations$Annotation(\"a\")",
           "@records.RecordWithAnnotations$AnnotationFieldOnly(\"b\")");
+  private static final String JVM_FROM_21_EXPECTED_RESULT =
+      JVM_UNTIL_20_EXPECTED_RESULT.replaceAll(
+          "RecordWithAnnotations\\$Annotation", "RecordWithAnnotations.Annotation");
   private static final String ART_EXPECTED_RESULT =
       StringUtils.lines(
           "Jane Doe",
@@ -219,29 +220,28 @@
     testForJvm(parameters)
         .addProgramClassFileData(PROGRAM_DATA)
         .run(parameters.getRuntime(), MAIN_TYPE)
-        .assertSuccessWithOutput(JVM_EXPECTED_RESULT);
+        .assertSuccessWithOutput(
+            parameters.getRuntime().asCf().getVm().isLessThanOrEqualTo(CfVm.JDK20)
+                ? JVM_UNTIL_20_EXPECTED_RESULT
+                : JVM_FROM_21_EXPECTED_RESULT);
   }
 
   @Test
   public void testDesugaring() throws Exception {
     parameters.assumeDexRuntime();
     assumeTrue(keepAnnotations);
-    // Android U will support records.
-    boolean compilingForNativeRecordSupport =
-        parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U);
-    boolean runtimeWithNativeRecordSupport =
-        parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V14_0_0);
     testForDesugaring(parameters)
         .addProgramClassFileData(PROGRAM_DATA)
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            compilingForNativeRecordSupport,
-            r -> r.assertSuccessWithOutput(ART_EXPECTED_RESULT),
+            isRecordsDesugaredForD8(parameters),
             r ->
                 r.assertSuccessWithOutput(
-                        !runtimeWithNativeRecordSupport
-                            ? EXPECTED_RESULT_DESUGARED_NO_RECORD_SUPPORT
-                            : EXPECTED_RESULT_DESUGARED_RECORD_SUPPORT)
+                    runtimeWithRecordsSupport(parameters.getRuntime())
+                        ? EXPECTED_RESULT_DESUGARED_RECORD_SUPPORT
+                        : EXPECTED_RESULT_DESUGARED_NO_RECORD_SUPPORT),
+            r ->
+                r.assertSuccessWithOutput(ART_EXPECTED_RESULT)
                     .inspect(
                         inspector -> {
                           ClassSubject person =
@@ -250,74 +250,60 @@
                           assertThat(name, isPresentAndNotRenamed());
                           FieldSubject age = person.uniqueFieldWithOriginalName("age");
                           assertThat(age, isPresentAndNotRenamed());
-                          if (compilingForNativeRecordSupport) {
-                            assertEquals(2, person.getFinalRecordComponents().size());
+                          assertEquals(2, person.getFinalRecordComponents().size());
 
-                            assertEquals(
-                                name.getFinalName(),
-                                person.getFinalRecordComponents().get(0).getName());
-                            assertTrue(
-                                person
-                                    .getFinalRecordComponents()
-                                    .get(0)
-                                    .getType()
-                                    .is("java.lang.String"));
-                            assertNull(person.getFinalRecordComponents().get(0).getSignature());
-                            assertEquals(
-                                2,
-                                person.getFinalRecordComponents().get(0).getAnnotations().size());
-                            assertThat(
-                                person.getFinalRecordComponents().get(0).getAnnotations(),
-                                hasAnnotationTypes(
-                                    inspector.getTypeSubject(
-                                        "records.RecordWithAnnotations$Annotation"),
-                                    inspector.getTypeSubject(
-                                        "records.RecordWithAnnotations$AnnotationRecordComponentOnly")));
-                            assertThat(
-                                person.getFinalRecordComponents().get(0).getAnnotations().get(0),
-                                hasElements(new Pair<>("value", "a")));
-                            assertThat(
-                                person.getFinalRecordComponents().get(0).getAnnotations().get(1),
-                                hasElements(new Pair<>("value", "c")));
+                          assertEquals(
+                              name.getFinalName(),
+                              person.getFinalRecordComponents().get(0).getName());
+                          assertTrue(
+                              person
+                                  .getFinalRecordComponents()
+                                  .get(0)
+                                  .getType()
+                                  .is("java.lang.String"));
+                          assertNull(person.getFinalRecordComponents().get(0).getSignature());
+                          assertEquals(
+                              2, person.getFinalRecordComponents().get(0).getAnnotations().size());
+                          assertThat(
+                              person.getFinalRecordComponents().get(0).getAnnotations(),
+                              hasAnnotationTypes(
+                                  inspector.getTypeSubject(
+                                      "records.RecordWithAnnotations$Annotation"),
+                                  inspector.getTypeSubject(
+                                      "records.RecordWithAnnotations$AnnotationRecordComponentOnly")));
+                          assertThat(
+                              person.getFinalRecordComponents().get(0).getAnnotations().get(0),
+                              hasElements(new Pair<>("value", "a")));
+                          assertThat(
+                              person.getFinalRecordComponents().get(0).getAnnotations().get(1),
+                              hasElements(new Pair<>("value", "c")));
 
-                            assertEquals(
-                                age.getFinalName(),
-                                person.getFinalRecordComponents().get(1).getName());
-                            assertTrue(
-                                person.getFinalRecordComponents().get(1).getType().is("int"));
-                            assertNull(person.getFinalRecordComponents().get(1).getSignature());
-                            assertEquals(
-                                2,
-                                person.getFinalRecordComponents().get(1).getAnnotations().size());
-                            assertThat(
-                                person.getFinalRecordComponents().get(1).getAnnotations(),
-                                hasAnnotationTypes(
-                                    inspector.getTypeSubject(
-                                        "records.RecordWithAnnotations$Annotation"),
-                                    inspector.getTypeSubject(
-                                        "records.RecordWithAnnotations$AnnotationRecordComponentOnly")));
-                            assertThat(
-                                person.getFinalRecordComponents().get(1).getAnnotations().get(0),
-                                hasElements(new Pair<>("value", "x")));
-                            assertThat(
-                                person.getFinalRecordComponents().get(1).getAnnotations().get(1),
-                                hasElements(new Pair<>("value", "z")));
-                          } else {
-                            assertEquals(0, person.getFinalRecordComponents().size());
-                          }
+                          assertEquals(
+                              age.getFinalName(),
+                              person.getFinalRecordComponents().get(1).getName());
+                          assertTrue(person.getFinalRecordComponents().get(1).getType().is("int"));
+                          assertNull(person.getFinalRecordComponents().get(1).getSignature());
+                          assertEquals(
+                              2, person.getFinalRecordComponents().get(1).getAnnotations().size());
+                          assertThat(
+                              person.getFinalRecordComponents().get(1).getAnnotations(),
+                              hasAnnotationTypes(
+                                  inspector.getTypeSubject(
+                                      "records.RecordWithAnnotations$Annotation"),
+                                  inspector.getTypeSubject(
+                                      "records.RecordWithAnnotations$AnnotationRecordComponentOnly")));
+                          assertThat(
+                              person.getFinalRecordComponents().get(1).getAnnotations().get(0),
+                              hasElements(new Pair<>("value", "x")));
+                          assertThat(
+                              person.getFinalRecordComponents().get(1).getAnnotations().get(1),
+                              hasElements(new Pair<>("value", "z")));
                         }));
   }
 
   @Test
   public void testR8() throws Exception {
     parameters.assumeR8TestParameters();
-    // Android U will support records.
-    boolean compilingForNativeRecordSupport =
-        parameters.isCfRuntime()
-            || parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U);
-    boolean runtimeWithNativeRecordSupport =
-        parameters.isCfRuntime()
-            || parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V14_0_0);
     testForR8(parameters.getBackend())
         .addProgramClassFileData(PROGRAM_DATA)
         // TODO(b/231930852): Change to android.jar for Androud U when that contains
@@ -337,7 +323,7 @@
               ClassSubject person = inspector.clazz("records.RecordWithAnnotations$Person");
               FieldSubject name = person.uniqueFieldWithOriginalName("name");
               FieldSubject age = person.uniqueFieldWithOriginalName("age");
-              if (compilingForNativeRecordSupport) {
+              if (!isRecordsDesugaredForR8(parameters)) {
                 assertEquals(2, person.getFinalRecordComponents().size());
 
                 assertEquals(
@@ -390,7 +376,7 @@
                     keepAnnotations
                         ? JVM_EXPECTED_RESULT_R8
                         : JVM_EXPECTED_RESULT_R8_NO_KEEP_ANNOTATIONS),
-            compilingForNativeRecordSupport,
+            !isRecordsDesugaredForR8(parameters),
             r ->
                 r.assertSuccessWithOutput(
                     keepAnnotations
@@ -398,7 +384,7 @@
                         : ART_EXPECTED_RESULT_R8_NO_KEEP_ANNOTATIONS),
             r ->
                 r.assertSuccessWithOutput(
-                    runtimeWithNativeRecordSupport
+                    runtimeWithRecordsSupport(parameters.getRuntime())
                         ? EXPECTED_RESULT_DESUGARED_RECORD_SUPPORT
                         : EXPECTED_RESULT_DESUGARED_NO_RECORD_SUPPORT));
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordComponentSignatureTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordComponentSignatureTest.java
index ff6732a..df192d0 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordComponentSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordComponentSignatureTest.java
@@ -15,8 +15,6 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.TestShrinkerBuilder;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
-import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -56,9 +54,9 @@
   private static final String EXPECTED_RESULT_R8_NO_KEEP_SIGNATURE =
       StringUtils.lines(
           "Jane Doe", "42", "Jane Doe", "42", "true", "1", "a", "java.lang.Object", "null", "0");
-  private static final String EXPECTED_RESULT_DESUGARED =
+  private static final String EXPECTED_RESULT_DESUGARED_NO_NATIVE_RECORDS_SUPPORT =
       StringUtils.lines("Jane Doe", "42", "Jane Doe", "42", "Class.isRecord not present");
-  private static final String EXPECTED_RESULT_DESUGARED_ART_14 =
+  private static final String EXPECTED_RESULT_DESUGARED_NATIVE_RECORD_SUPPORT =
       StringUtils.lines("Jane Doe", "42", "Jane Doe", "42", "false");
 
   @Parameter(0)
@@ -92,29 +90,23 @@
   public void testDesugaring() throws Exception {
     parameters.assumeDexRuntime();
     assumeTrue(keepSignatures);
-    // Android U will support records.
-    boolean compilingForNativeRecordSupport =
-        parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U);
-    boolean runningWithNativeRecordSupport =
-        parameters.getRuntime().isDex()
-            && parameters.getRuntime().asDex().getVersion().isNewerThanOrEqual(Version.V14_0_0);
     testForDesugaring(parameters)
         .addProgramClassFileData(PROGRAM_DATA)
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            compilingForNativeRecordSupport,
+            !isRecordsDesugaredForD8(parameters),
             // Current Art 14 build does not support the java.lang.Record class.
             r -> r.assertSuccessWithOutput(EXPECTED_RESULT),
             r ->
                 r.assertSuccessWithOutput(
-                        runningWithNativeRecordSupport
-                            ? EXPECTED_RESULT_DESUGARED_ART_14
-                            : EXPECTED_RESULT_DESUGARED)
+                        runtimeWithRecordsSupport(parameters.getRuntime())
+                            ? EXPECTED_RESULT_DESUGARED_NATIVE_RECORD_SUPPORT
+                            : EXPECTED_RESULT_DESUGARED_NO_NATIVE_RECORDS_SUPPORT)
                     .inspect(
                         inspector -> {
                           ClassSubject person =
                               inspector.clazz("records.RecordWithSignature$Person");
-                          if (compilingForNativeRecordSupport) {
+                          if (!isRecordsDesugaredForD8(parameters)) {
                             assertEquals(2, person.getFinalRecordComponents().size());
 
                             assertEquals(
@@ -152,15 +144,9 @@
   @Test
   public void testR8() throws Exception {
     parameters.assumeR8TestParameters();
-    boolean compilingForNativeRecordSupport =
-        parameters.isCfRuntime()
-            || parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U);
-    boolean runningWithNativeRecordSupport =
-        parameters.getRuntime().isDex()
-            && parameters.getRuntime().asDex().getVersion().isNewerThanOrEqual(Version.V14_0_0);
     testForR8(parameters.getBackend())
         .addProgramClassFileData(PROGRAM_DATA)
-        // TODO(b/231930852): Change to android.jar for Androud U when that contains
+        // TODO(b/231930852): Change to android.jar for Android U when that contains
         // java.lang.Record.
         .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
         .addKeepMainRule(MAIN_TYPE)
@@ -171,7 +157,7 @@
             inspector -> {
               ClassSubject person = inspector.clazz("records.RecordWithSignature$Person");
               FieldSubject age = person.uniqueFieldWithOriginalName("age");
-              if (compilingForNativeRecordSupport) {
+              if (!isRecordsDesugaredForR8(parameters)) {
                 assertThat(age, isPresentAndRenamed());
                 assertEquals(1, person.getFinalRecordComponents().size());
                 assertEquals(
@@ -190,16 +176,15 @@
               }
             })
         .run(parameters.getRuntime(), MAIN_TYPE)
-        // No Art VM actually supports the java.lang.Record class.
         .applyIf(
-            compilingForNativeRecordSupport,
+            runtimeWithRecordsSupport(parameters.getRuntime()),
             r ->
                 r.assertSuccessWithOutput(
-                    keepSignatures ? EXPECTED_RESULT_R8 : EXPECTED_RESULT_R8_NO_KEEP_SIGNATURE),
-            r ->
-                r.assertSuccessWithOutput(
-                    runningWithNativeRecordSupport
-                        ? EXPECTED_RESULT_DESUGARED_ART_14
-                        : EXPECTED_RESULT_DESUGARED));
+                    isRecordsDesugaredForR8(parameters)
+                        ? EXPECTED_RESULT_DESUGARED_NATIVE_RECORD_SUPPORT
+                        : (keepSignatures
+                            ? EXPECTED_RESULT_R8
+                            : EXPECTED_RESULT_R8_NO_KEEP_SIGNATURE)),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_DESUGARED_NO_NATIVE_RECORDS_SUPPORT));
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInterfaceTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInterfaceTest.java
index 0c63278..7e1d2c7 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInterfaceTest.java
@@ -66,9 +66,10 @@
         .setMinApi(parameters)
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT),
+            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
   }
 
   @Test
@@ -80,11 +81,11 @@
     testForD8()
         .addProgramFiles(path)
         .applyIf(
-            canUseNativeRecords(parameters),
-            b -> assertFalse(globals.hasGlobals()),
+            isRecordsDesugaredForD8(parameters),
             b ->
                 b.getBuilder()
-                    .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
+                    .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()),
+            b -> assertFalse(globals.hasGlobals()))
         .apply(b -> b.getBuilder().setDesugarGraphConsumer(consumer))
         .setMinApi(parameters)
         .setIncludeClassesChecksum(true)
@@ -104,11 +105,11 @@
     testForD8()
         .addProgramFiles(path)
         .applyIf(
-            canUseNativeRecords(parameters),
-            b -> assertFalse(globals.hasGlobals()),
+            isRecordsDesugaredForD8(parameters),
             b ->
                 b.getBuilder()
-                    .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
+                    .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()),
+            b -> assertFalse(globals.hasGlobals()))
         .apply(b -> b.getBuilder().setDesugarGraphConsumer(consumer))
         .setMinApi(parameters)
         .setIncludeClassesChecksum(true)
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
index 214afea..ca9fc51 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordInvokeCustomSplitDesugaringTest.java
@@ -4,12 +4,18 @@
 
 package com.android.tools.r8.desugar.records;
 
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.ZipUtils;
 import java.nio.file.Path;
@@ -41,8 +47,6 @@
       String.format(EXPECTED_RESULT, "Empty", "Person", "name", "age");
   private static final String EXPECTED_RESULT_R8 =
       String.format(EXPECTED_RESULT, "a", "b", "name", "age");
-  private static final String EXPECTED_RESULT_R8_2 =
-      String.format(EXPECTED_RESULT, "a", "b", "a", "b");
 
   private final TestParameters parameters;
 
@@ -52,7 +56,7 @@
 
   @Parameterized.Parameters(name = "{0}")
   public static TestParametersCollection data() {
-    return getTestParameters().withDexRuntimes().withAllApiLevelsAlsoForCf().build();
+    return getTestParameters().withDexRuntimesAndAllApiLevels().build();
   }
 
   @Test
@@ -80,17 +84,32 @@
             .setMinApi(parameters)
             .compile()
             .writeToZip();
-    if (canUseNativeRecords(parameters)) {
-      assertFalse(ZipUtils.containsEntry(desugared, "com/android/tools/r8/RecordTag.class"));
-    } else {
+    if (isRecordsDesugaredForD8(parameters)) {
       assertTrue(ZipUtils.containsEntry(desugared, "com/android/tools/r8/RecordTag.class"));
+    } else {
+      assertFalse(ZipUtils.containsEntry(desugared, "com/android/tools/r8/RecordTag.class"));
     }
     testForR8(parameters.getBackend())
         .addProgramFiles(desugared)
         .setMinApi(parameters)
         .addKeepMainRule(MAIN_TYPE)
+        .allowDiagnosticMessages()
+        .compileWithExpectedDiagnostics(
+            // Class com.android.tools.r8.RecordTag in desugared input is seen as java.lang.Record
+            // when reading causing the duplicate class.
+            diagnostics -> {
+              if (parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U)) {
+                diagnostics
+                    .assertNoErrors()
+                    .assertWarningsMatch(
+                        allOf(
+                            diagnosticType(StringDiagnostic.class),
+                            diagnosticMessage(containsString("java.lang.Record"))));
+              } else {
+                diagnostics.assertNoMessages();
+              }
+            })
         .run(parameters.getRuntime(), MAIN_TYPE)
-        .assertSuccessWithOutput(
-            canUseNativeRecords(parameters) ? EXPECTED_RESULT_R8_2 : EXPECTED_RESULT_R8);
+        .assertSuccessWithOutput(EXPECTED_RESULT_R8);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
index 38954bf..a46c400 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
@@ -74,9 +74,7 @@
             .addProgramClassFileData(PROGRAM_DATA_1)
             .setMinApi(parameters)
             .setIntermediate(true);
-    if (canUseNativeRecords(parameters)) {
-      builder.compile();
-    } else {
+    if (isRecordsDesugaredForD8(parameters)) {
       assertThrows(
           CompilationFailedException.class,
           () ->
@@ -86,6 +84,8 @@
                           .assertOnlyErrors()
                           .assertErrorsMatch(
                               diagnosticType(MissingGlobalSyntheticsConsumerDiagnostic.class))));
+    } else {
+      builder.compile();
     }
   }
 
@@ -129,8 +129,8 @@
             .inspect(this::assertDoesNotHaveRecordTag)
             .writeToZip();
 
-    assertTrue(canUseNativeRecords(parameters) ^ globals1.hasGlobals());
-    assertTrue(canUseNativeRecords(parameters) ^ globals2.hasGlobals());
+    assertTrue(isRecordsDesugaredForD8(parameters) ^ !globals1.hasGlobals());
+    assertTrue(isRecordsDesugaredForD8(parameters) ^ !globals2.hasGlobals());
 
     D8TestCompileResult result =
         testForD8(parameters.getBackend())
@@ -147,15 +147,17 @@
     result
         .run(parameters.getRuntime(), MAIN_TYPE_1)
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_1));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_1),
+            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
     result
         .run(parameters.getRuntime(), MAIN_TYPE_2)
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_2));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_2),
+            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
   }
 
   @Test
@@ -181,15 +183,17 @@
     result
         .run(parameters.getRuntime(), MAIN_TYPE_1)
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_1));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_1),
+            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
     result
         .run(parameters.getRuntime(), MAIN_TYPE_2)
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_2));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT_2),
+            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
   }
 
   @Test
@@ -210,7 +214,7 @@
             .inspect(this::assertHasRecordTag)
             .writeToZip();
 
-    if (canUseNativeRecords(parameters)) {
+    if (!isRecordsDesugaredForD8(parameters)) {
       D8TestCompileResult result =
           testForD8(parameters.getBackend())
               .addProgramFiles(output1, output2)
@@ -219,17 +223,17 @@
       result
           .run(parameters.getRuntime(), MAIN_TYPE_1)
           .applyIf(
-              canUseNativeRecords(parameters)
-                  && !runtimeWithRecordsSupport(parameters.getRuntime()),
-              r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-              r -> r.assertSuccessWithOutput(EXPECTED_RESULT_1));
+              isRecordsDesugaredForD8(parameters)
+                  || runtimeWithRecordsSupport(parameters.getRuntime()),
+              r -> r.assertSuccessWithOutput(EXPECTED_RESULT_1),
+              r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
       result
           .run(parameters.getRuntime(), MAIN_TYPE_2)
           .applyIf(
-              canUseNativeRecords(parameters)
-                  && !runtimeWithRecordsSupport(parameters.getRuntime()),
-              r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-              r -> r.assertSuccessWithOutput(EXPECTED_RESULT_2));
+              isRecordsDesugaredForD8(parameters)
+                  || runtimeWithRecordsSupport(parameters.getRuntime()),
+              r -> r.assertSuccessWithOutput(EXPECTED_RESULT_2),
+              r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
     } else {
       assertThrows(
           CompilationFailedException.class,
@@ -247,7 +251,8 @@
 
   private void assertHasRecordTag(CodeInspector inspector) {
     // Note: this should be asserting on record tag.
-    assertThat(inspector.clazz("java.lang.Record"), isPresentIf(!canUseNativeRecords(parameters)));
+    assertThat(
+        inspector.clazz("java.lang.Record"), isPresentIf(isRecordsDesugaredForD8(parameters)));
   }
 
   private void assertDoesNotHaveRecordTag(CodeInspector inspector) {
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
index 5ed96ab..24757af 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.desugar.records;
 
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
@@ -77,7 +76,6 @@
   @Test
   public void testD8() throws Exception {
     assumeFalse(forceInvokeRangeForInvokeCustom);
-    boolean runningWithNativeRecordSupport = runtimeWithRecordsSupport(parameters.getRuntime());
     testForD8(parameters.getBackend())
         .addProgramClassFileData(PROGRAM_DATA)
         .setMinApi(parameters)
@@ -87,9 +85,10 @@
             options -> options.testing.disableRecordApplicationReaderMap = true)
         .run(parameters.getRuntime(), MAIN_TYPE)
         .applyIf(
-            canUseNativeRecords(parameters) && !runningWithNativeRecordSupport,
-            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT),
+            r -> r.assertFailureWithErrorThatThrows(NoClassDefFoundError.class));
     ;
   }
 
@@ -101,9 +100,7 @@
     Path path = compileIntermediate(globals);
     testForD8()
         .addProgramFiles(path)
-        .applyIf(
-            parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U),
-            b -> assertFalse(globals.hasGlobals()),
+        .apply(
             b ->
                 b.getBuilder()
                     .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
@@ -122,9 +119,7 @@
     // In Android Studio they disable desugaring at this point to improve build speed.
     testForD8()
         .addProgramFiles(path)
-        .applyIf(
-            parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.U),
-            b -> assertFalse(globals.hasGlobals()),
+        .apply(
             b ->
                 b.getBuilder()
                     .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java
index 1abf7a4..6633984 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java
@@ -19,7 +19,6 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.desugar.records.RecordTestUtils;
 import com.android.tools.r8.profile.art.model.ExternalArtProfile;
 import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
@@ -102,9 +101,10 @@
                     options -> options.testing.disableRecordApplicationReaderMap = true))
         .run(parameters.getRuntime(), MAIN_REFERENCE.getTypeName())
         .applyIf(
-            canUseNativeRecords(parameters) && !runtimeWithRecordsSupport(parameters.getRuntime()),
-            r -> r.assertFailureWithErrorThatThrows(ClassNotFoundException.class),
-            r -> r.assertSuccessWithOutput(EXPECTED_RESULT));
+            isRecordsDesugaredForD8(parameters)
+                || runtimeWithRecordsSupport(parameters.getRuntime()),
+            r -> r.assertSuccessWithOutput(EXPECTED_RESULT),
+            r -> r.assertFailureWithErrorThatThrows(ClassNotFoundException.class));
   }
 
   @Test
@@ -166,7 +166,7 @@
         SyntheticItemsTestUtils.syntheticRecordTagClass(),
         false,
         parameters.canUseNestBasedAccessesWhenDesugaring(),
-        canUseNativeRecords(parameters));
+        !isRecordsDesugaredForD8(parameters));
   }
 
   private void inspectR8(ArtProfileInspector profileInspector, CodeInspector inspector) {
@@ -176,7 +176,7 @@
         RECORD_REFERENCE,
         parameters.canHaveNonReboundConstructorInvoke(),
         parameters.canUseNestBasedAccesses(),
-        canUseNativeRecords(parameters) || parameters.isCfRuntime());
+        !isRecordsDesugaredForR8(parameters));
   }
 
   private void inspect(
@@ -211,15 +211,7 @@
             ? inspector.getTypeSubject(RECORD_REFERENCE.getTypeName())
             : recordTagClassSubject.asTypeSubject(),
         personRecordClassSubject.getSuperType());
-    assertEquals(
-        canUseRecords
-            ? (parameters.isCfRuntime()
-                    && parameters.asCfRuntime().isNewerThanOrEqual(CfVm.JDK17)
-                    && !canUseNativeRecords(parameters)
-                ? 6
-                : 8)
-            : 10,
-        personRecordClassSubject.allMethods().size());
+    assertEquals(canUseRecords ? 6 : 10, personRecordClassSubject.allMethods().size());
 
     MethodSubject personInstanceInitializerSubject =
         personRecordClassSubject.uniqueInstanceInitializer();