Rewrite ConstDynamic with ClassDesc

Change-Id: I8661e816eca91a42fc749633eb9a6948dbbf2a56
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
index 963df0f..b125b83 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
@@ -150,7 +150,7 @@
     for (int i = 0; i < rewrittenArguments.size(); i++) {
       bsmArgs[i] =
           CfInvokeDynamic.decodeBootstrapArgument(
-              rewrittenArguments.get(i), namingLens, dexItemFactory);
+              rewrittenArguments.get(i), namingLens, appView, context);
     }
     ConstantDynamic constantDynamic =
         new ConstantDynamic(
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index a1fed4c..b8d79e9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -6,6 +6,7 @@
 import com.android.tools.r8.cf.CfPrinter;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.CfCodeDiagnostics;
 import com.android.tools.r8.graph.CfCompareHelper;
 import com.android.tools.r8.graph.DexCallSite;
 import com.android.tools.r8.graph.DexClassAndMethod;
@@ -14,6 +15,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexValue;
+import com.android.tools.r8.graph.DexValue.DexValueString;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.UseRegistry;
 import com.android.tools.r8.graph.lens.GraphLens;
@@ -27,6 +29,7 @@
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
 import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
+import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.structural.CompareToVisitor;
 import com.android.tools.r8.utils.structural.HashingVisitor;
 import java.util.ArrayList;
@@ -88,7 +91,7 @@
     List<DexValue> bootstrapArgs = rewrittenCallSite.bootstrapArgs;
     Object[] bsmArgs = new Object[bootstrapArgs.size()];
     for (int i = 0; i < bootstrapArgs.size(); i++) {
-      bsmArgs[i] = decodeBootstrapArgument(bootstrapArgs.get(i), namingLens, dexItemFactory);
+      bsmArgs[i] = decodeBootstrapArgument(bootstrapArgs.get(i), namingLens, appView, context);
     }
     Handle bsmHandle = bootstrapMethod.toAsmHandle(namingLens);
     DexString methodName = namingLens.lookupMethodName(rewrittenCallSite, appView);
@@ -105,7 +108,7 @@
   }
 
   public static Object decodeBootstrapArgument(
-      DexValue value, NamingLens lens, DexItemFactory factory) {
+      DexValue value, NamingLens lens, AppView<?> appView, ProgramMethod context) {
     switch (value.getValueKind()) {
       case DOUBLE:
         return value.asDexValueDouble().getValue();
@@ -128,8 +131,11 @@
         ConstantDynamicReference ref = value.asDexValueConstDynamic().getValue();
         List<DexValue> bootstrapArgs = ref.getBootstrapMethodArguments();
         Object[] bsmArgs = new Object[bootstrapArgs.size()];
-        for (int i = 0; i < bootstrapArgs.size(); i++) {
-          bsmArgs[i] = CfInvokeDynamic.decodeBootstrapArgument(bootstrapArgs.get(i), lens, factory);
+        DexItemFactory factory = appView.dexItemFactory();
+        if (ref.getType().isIdenticalTo(factory.classDescType)) {
+          decodeClassDescBootstrapArgs(lens, bootstrapArgs, bsmArgs, appView, context);
+        } else {
+          decodeBootstrapArgs(lens, bootstrapArgs, bsmArgs, appView, context);
         }
         return new ConstantDynamic(
             ref.getName().toString(),
@@ -142,6 +148,49 @@
     }
   }
 
+  private static void decodeBootstrapArgs(
+      NamingLens lens,
+      List<DexValue> bootstrapArgs,
+      Object[] bsmArgs,
+      AppView<?> appView,
+      ProgramMethod context) {
+    for (int i = 0; i < bootstrapArgs.size(); i++) {
+      bsmArgs[i] =
+          CfInvokeDynamic.decodeBootstrapArgument(bootstrapArgs.get(i), lens, appView, context);
+    }
+  }
+
+  private static void decodeClassDescBootstrapArgs(
+      NamingLens lens,
+      List<DexValue> bootstrapArgs,
+      Object[] bsmArgs,
+      AppView<?> appView,
+      ProgramMethod context) {
+    if (bootstrapArgs.size() != 2 || !bootstrapArgs.get(1).isDexValueString()) {
+      appView
+          .reporter()
+          .warning(
+              new CfCodeDiagnostics(
+                  context, "Unexpected ClassDesc bootstrap arguments " + bootstrapArgs));
+      decodeBootstrapArgs(lens, bootstrapArgs, bsmArgs, appView, context);
+      return;
+    }
+    bsmArgs[0] =
+        CfInvokeDynamic.decodeBootstrapArgument(bootstrapArgs.get(0), lens, appView, context);
+    DexValueString className = bootstrapArgs.get(1).asDexValueString();
+    DexItemFactory factory = appView.dexItemFactory();
+    DexType rewrittenType =
+        lens.lookupType(
+            factory.createType(
+                DescriptorUtils.javaTypeToDescriptor(className.getValue().toString())),
+            factory);
+    DexString rewrittenValue =
+        factory.createString(
+            DescriptorUtils.descriptorToJavaType(rewrittenType.getDescriptor().toString()));
+    assert rewrittenValue != null;
+    bsmArgs[1] = rewrittenValue.toString();
+  }
+
   @Override
   public void print(CfPrinter printer) {
     printer.print(this);
diff --git a/src/main/java/com/android/tools/r8/graph/UseRegistry.java b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
index e3f2ba6..d138d31 100644
--- a/src/main/java/com/android/tools/r8/graph/UseRegistry.java
+++ b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
@@ -269,12 +269,13 @@
               .getValue()
               .getType()
               .isIdenticalTo(appView.dexItemFactory().enumDescType)) {
-            DexField enumField =
-                TypeSwitchDesugaringHelper.extractEnumField(
-                    arg.asDexValueConstDynamic(), getMethodContext(), appView);
-            if (enumField != null) {
-              registerStaticFieldRead(enumField);
-            }
+            TypeSwitchDesugaringHelper.dispatchEnumField(
+                (type, fieldName) -> {
+                  registerTypeReference(type);
+                },
+                arg.asDexValueConstDynamic().getValue(),
+                context,
+                dexItemFactory());
           }
           break;
         default:
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
index 776debb..898f0f9 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
@@ -190,8 +190,7 @@
       if (dexValue.isDexValueType()) {
         dexTypeConsumer.accept(dexValue.asDexValueType().getValue());
       } else if (dexValue.isDexValueString()) {
-        enumConsumer.accept(
-            factory.createString(enumType.getTypeName()), dexValue.asDexValueString().getValue());
+        enumConsumer.accept(enumType, dexValue.asDexValueString().getValue());
       } else {
         throw new CompilationError(
             "Invalid bootstrap arg for enum switch " + dexValue, context.getOrigin());
@@ -227,7 +226,7 @@
           dispatchBooleanField(context, dexValue, booleanConsumer, constDynamic);
         } else {
           assert constDynamic.getType().isIdenticalTo(factory.enumDescType);
-          dispatchEnumField(enumConsumer, constDynamic, context, appView);
+          dispatchEnumField(enumConsumer, constDynamic, context, appView.dexItemFactory());
         }
       } else if (dexValue.isDexValueNumber()) {
         assert dexValue.isDexValueDouble()
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java
index da7fc02..2780c66 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java
@@ -5,12 +5,8 @@
 package com.android.tools.r8.ir.desugar.typeswitch;
 
 import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
 import com.android.tools.r8.graph.DexCallSite;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexMethodHandle;
@@ -18,14 +14,12 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexValue;
-import com.android.tools.r8.graph.DexValue.DexValueConstDynamic;
 import com.android.tools.r8.ir.desugar.constantdynamic.ConstantDynamicReference;
 import com.android.tools.r8.utils.DescriptorUtils;
 import java.util.function.BiConsumer;
 
 public class TypeSwitchDesugaringHelper {
-  private static CompilationError throwEnumFieldConstantDynamic(
-      String msg, DexClassAndMethod context) {
+  private static CompilationError throwEnumFieldConstantDynamic(String msg, Definition context) {
     throw new CompilationError(
         "Unexpected ConstantDynamic in TypeSwitch: " + msg, context.getOrigin());
   }
@@ -67,11 +61,10 @@
   }
 
   public static void dispatchEnumField(
-      BiConsumer<DexString, DexString> enumConsumer,
+      BiConsumer<DexType, DexString> enumConsumer,
       ConstantDynamicReference enumCstDynamic,
-      DexClassAndMethod context,
-      AppView<?> appView) {
-    DexItemFactory factory = appView.dexItemFactory();
+      Definition context,
+      DexItemFactory factory) {
     DexMethod bootstrapMethod = factory.constantDynamicBootstrapMethod;
     if (!(enumCstDynamic.getType().isIdenticalTo(factory.enumDescType)
         && enumCstDynamic.getName().isIdenticalTo(bootstrapMethod.getName())
@@ -106,65 +99,7 @@
       throw throwEnumFieldConstantDynamic("Class name " + dexValueClassName, context);
     }
     DexString className = dexValueClassName.asDexValueString().getValue();
-    enumConsumer.accept(className, fieldName);
-  }
-
-  public static DexField extractEnumField(
-      DexValueConstDynamic dexValueConstDynamic, DexClassAndMethod context, AppView<?> appView) {
-    DexItemFactory factory = appView.dexItemFactory();
-    ConstantDynamicReference enumCstDynamic = dexValueConstDynamic.getValue();
-    DexMethod bootstrapMethod = factory.constantDynamicBootstrapMethod;
-    if (!(enumCstDynamic.getType().isIdenticalTo(factory.enumDescType)
-        && enumCstDynamic.getName().isIdenticalTo(bootstrapMethod.getName())
-        && enumCstDynamic.getBootstrapMethod().asMethod().isIdenticalTo(bootstrapMethod)
-        && enumCstDynamic.getBootstrapMethodArguments().size() == 3
-        && methodHandleIsInvokeStaticTo(
-            enumCstDynamic.getBootstrapMethodArguments().get(0), factory.enumDescMethod))) {
-      throw throwEnumFieldConstantDynamic("Invalid EnumDesc", context);
-    }
-    DexValue dexValueFieldName = enumCstDynamic.getBootstrapMethodArguments().get(2);
-    if (!dexValueFieldName.isDexValueString()) {
-      throw throwEnumFieldConstantDynamic("Field name " + dexValueFieldName, context);
-    }
-    DexString fieldName = dexValueFieldName.asDexValueString().getValue();
-
-    DexValue dexValueClassCstDynamic = enumCstDynamic.getBootstrapMethodArguments().get(1);
-    if (!dexValueClassCstDynamic.isDexValueConstDynamic()) {
-      throw throwEnumFieldConstantDynamic("Enum class " + dexValueClassCstDynamic, context);
-    }
-    ConstantDynamicReference classCstDynamic =
-        dexValueClassCstDynamic.asDexValueConstDynamic().getValue();
-    if (!(classCstDynamic.getType().isIdenticalTo(factory.classDescType)
-        && classCstDynamic.getName().isIdenticalTo(bootstrapMethod.getName())
-        && classCstDynamic.getBootstrapMethod().asMethod().isIdenticalTo(bootstrapMethod)
-        && classCstDynamic.getBootstrapMethodArguments().size() == 2
-        && methodHandleIsInvokeStaticTo(
-            classCstDynamic.getBootstrapMethodArguments().get(0), factory.classDescMethod))) {
-      throw throwEnumFieldConstantDynamic("Class descriptor " + classCstDynamic, context);
-    }
-    DexValue dexValueClassName = classCstDynamic.getBootstrapMethodArguments().get(1);
-    if (!dexValueClassName.isDexValueString()) {
-      throw throwEnumFieldConstantDynamic("Class name " + dexValueClassName, context);
-    }
-    DexString className = dexValueClassName.asDexValueString().getValue();
-    DexType enumType =
-        factory.createType(DescriptorUtils.javaTypeToDescriptor(className.toString()));
-    return getEnumField(fieldName, enumType, appView);
-  }
-
-  public static DexField getEnumField(DexString fieldName, DexType enumType, AppView<?> appView) {
-    DexClass enumClass = appView.appInfo().definitionForWithoutExistenceAssert(enumType);
-    if (enumClass == null) {
-      // If the enum class is missing, the case is (interestingly) considered unreachable and
-      // effectively removed from the switch (base on jdk 21 behavior).
-      return null;
-    }
-    DexEncodedField dexEncodedField = enumClass.lookupUniqueStaticFieldWithName(fieldName);
-    if (dexEncodedField == null) {
-      // If the field is missing, but the class is there, the case is considered unreachable and
-      // effectively removed from the switch.
-      return null;
-    }
-    return dexEncodedField.getReference();
+    DexType type = factory.createType(DescriptorUtils.javaTypeToDescriptor(className.toString()));
+    enumConsumer.accept(type, fieldName);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
index 0edb7aa..2b7c39c 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
@@ -63,7 +63,7 @@
         Consumer<DexType> dexTypeConsumer,
         IntConsumer intValueConsumer,
         Consumer<DexString> dexStringConsumer,
-        BiConsumer<DexString, DexString> enumConsumer,
+        BiConsumer<DexType, DexString> enumConsumer,
         Consumer<Boolean> booleanConsumer,
         Consumer<DexValueNumber> numberConsumer);
   }
@@ -186,7 +186,7 @@
                   instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
                   instructions.add(new CfReturn(ValueType.INT));
                 },
-                (enumClass, enumField) -> {
+                (type, enumField) -> {
                   instructions.add(cfLabels.get(index.get()));
                   instructions.add(frame);
                   // TODO(b/399808482): In R8 release, we can analyze at compile-time program enum
@@ -197,15 +197,15 @@
                   instructions.add(new CfStaticFieldRead(enumFieldCache));
                   instructions.add(new CfConstNumber(enumIndex.getAndIncrement(), ValueType.INT));
                   if (appView.enableWholeProgramOptimizations()) {
-                    DexType type =
-                        factory.createType(
-                            DescriptorUtils.javaTypeToDescriptor(enumClass.toString()));
                     instructions.add(
                         new CfDexItemBasedConstString(
                             type,
                             ClassNameComputationInfo.create(NAME, type.getArrayTypeDimensions())));
                   } else {
-                    instructions.add(new CfConstString(enumClass));
+                    DexString typeString =
+                        factory.createString(
+                            DescriptorUtils.descriptorToJavaType(type.toDescriptorString()));
+                    instructions.add(new CfConstString(typeString));
                   }
                   instructions.add(new CfConstString(enumField));
                   assert enumEq != null;
diff --git a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
index 14877d0..1e92c88 100644
--- a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
@@ -5,8 +5,6 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.ir.desugar.records.RecordRewriterHelper.isInvokeDynamicOnRecord;
-import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.extractEnumField;
-import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.getEnumField;
 import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isEnumSwitchCallSite;
 import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isTypeSwitchCallSite;
 import static com.android.tools.r8.utils.MapUtils.ignoreKey;
@@ -16,6 +14,7 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexCallSite;
+import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
@@ -23,13 +22,13 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexMethodHandle;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexValue;
 import com.android.tools.r8.graph.OriginalFieldWitness;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.InvokeType;
 import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper;
 import com.google.common.collect.Sets;
 import java.util.IdentityHashMap;
 import java.util.ListIterator;
@@ -213,11 +212,6 @@
     enqueuer.traceStaticFieldReadFromMethodHandle(field, getContext());
   }
 
-  private void registerStaticFieldReadFromSwitchMethodHandle(DexField field) {
-    super.registerStaticFieldReadFromMethodHandle(field);
-    enqueuer.traceStaticFieldReadFromSwitchMethodHandle(field, getContext());
-  }
-
   @Override
   public void registerStaticFieldWrite(DexField field) {
     super.registerStaticFieldWrite(field);
@@ -290,7 +284,16 @@
     enqueuer.traceCallSite(callSite, getContext(), this);
   }
 
-  private void registerEnumMethods(DexType enumType) {
+  private void registerEnumReferencedInTypeSwitchBootstrapArguments(DexType enumType) {
+    DexClass dexClass = appView.definitionFor(enumType);
+    if (dexClass == null || dexClass.isNotProgramClass()) {
+      return;
+    }
+    // The enum class cannot be unboxed or class merged. It can however be renamed.
+    enqueuer
+        .getKeepInfo()
+        .joinClass(
+            dexClass.asProgramClass(), joiner -> joiner.disallowOptimization().disallowShrinking());
     DexItemFactory factory = dexItemFactory();
     DexMethod values =
         factory.createMethod(
@@ -314,12 +317,13 @@
               .getValue()
               .getType()
               .isIdenticalTo(appView.dexItemFactory().enumDescType)) {
-        DexField enumField =
-            extractEnumField(bootstrapArg.asDexValueConstDynamic(), getContext(), appView);
-        if (enumField != null) {
-          registerStaticFieldReadFromSwitchMethodHandle(enumField);
-          registerEnumMethods(enumField.getHolderType());
-        }
+        TypeSwitchDesugaringHelper.dispatchEnumField(
+            (type, fieldName) -> {
+              registerEnumReferencedInTypeSwitchBootstrapArguments(type);
+            },
+            bootstrapArg.asDexValueConstDynamic().getValue(),
+            getContext(),
+            dexItemFactory());
       }
     }
   }
@@ -330,12 +334,7 @@
       if (bootstrapArg.isDexValueType()) {
         registerTypeReference(bootstrapArg.asDexValueType().value);
       } else if (bootstrapArg.isDexValueString()) {
-        DexString fieldName = bootstrapArg.asDexValueString().value;
-        DexField enumField = getEnumField(fieldName, enumType, appView);
-        if (enumField != null) {
-          registerStaticFieldReadFromSwitchMethodHandle(enumField);
-          registerEnumMethods(enumType);
-        }
+        registerEnumReferencedInTypeSwitchBootstrapArguments(enumType);
       }
     }
   }
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 8cee863..7fb2bf6 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1803,15 +1803,12 @@
     private static final int DEFERRED_MASK = 1;
     private static final int FROM_METHOD_HANDLE_MASK = 2;
     private static final int FROM_RECORD_METHOD_HANDLE_MASK = 4;
-    private static final int FROM_SWITCH_METHOD_HANDLE_MASK = 8;
 
     static FieldAccessMetadata DEFAULT = new FieldAccessMetadata(0);
     static FieldAccessMetadata FROM_METHOD_HANDLE =
         new FieldAccessMetadata(FROM_METHOD_HANDLE_MASK);
     static FieldAccessMetadata FROM_RECORD_METHOD_HANDLE =
         new FieldAccessMetadata(FROM_RECORD_METHOD_HANDLE_MASK);
-    static FieldAccessMetadata FROM_SWITCH_METHOD_HANDLE =
-        new FieldAccessMetadata(FROM_SWITCH_METHOD_HANDLE_MASK);
 
     private final FieldAccessMetadata deferred;
     private final int flags;
@@ -1833,10 +1830,6 @@
       return (flags & FROM_RECORD_METHOD_HANDLE_MASK) != 0;
     }
 
-    boolean isFromSwitchMethodHandle() {
-      return (flags & FROM_SWITCH_METHOD_HANDLE_MASK) != 0;
-    }
-
     public FieldAccessMetadata toDeferred() {
       return deferred;
     }
@@ -1948,11 +1941,6 @@
   void traceStaticFieldReadFromMethodHandle(DexField field, ProgramMethod currentMethod) {
     traceStaticFieldRead(field, currentMethod, FieldAccessMetadata.FROM_METHOD_HANDLE);
   }
-
-  void traceStaticFieldReadFromSwitchMethodHandle(DexField field, ProgramMethod currentMethod) {
-    traceStaticFieldRead(field, currentMethod, FieldAccessMetadata.FROM_SWITCH_METHOD_HANDLE);
-  }
-
   void traceStaticFieldRead(
       DexField fieldReference, ProgramMethod currentMethod, FieldAccessMetadata metadata) {
     traceStaticFieldAccess(fieldReference, currentMethod, FieldAccessKind.STATIC_READ, metadata);
@@ -2033,16 +2021,6 @@
             fieldAccessInfoCollection
                 .get(field.getReference())
                 .setAccessedFromMethodHandle(accessKind);
-          } else if (metadata.isFromSwitchMethodHandle()) {
-            assert accessKind.isRead();
-            // TODO(b/340187630): This disables any optimization on such enum fields. We could
-            //  support rewriting fields in switch method handles instead.
-            keepInfo.joinClass(
-                field.getHolder(),
-                joiner -> joiner.disallowMinification().disallowOptimization().disallowShrinking());
-            keepInfo.joinField(
-                field,
-                joiner -> joiner.disallowMinification().disallowOptimization().disallowShrinking());
           }
 
           markFieldAsLive(field, currentMethod);
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java
index 78bb2ef..9f63637 100644
--- a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java
@@ -80,6 +80,71 @@
 
   static class Main {
 
+    // static void booleanSwitch(Boolean b) {
+    //   switch (b) {
+    //     case null -> {
+    //       System.out.println("null");
+    //     }
+    //     case true -> {
+    //       System.out.println("true");
+    //     }
+    //     default -> {
+    //       System.out.println("false");
+    //     }
+    //   }
+    // }
+    //
+    // static void doubleSwitch(Double d) {
+    //   switch (d) {
+    //     case null -> {
+    //       System.out.println("null");
+    //     }
+    //     case 42.0 -> {
+    //       System.out.println("42");
+    //     }
+    //     case Double f2 when f2 > 0 -> {
+    //       System.out.println("positif");
+    //     }
+    //     default -> {
+    //       System.out.println("negatif");
+    //     }
+    //   }
+    // }
+    //
+    // static void floatSwitch(Float f) {
+    //   switch (f) {
+    //     case null -> {
+    //       System.out.println("null");
+    //     }
+    //     case 42.0f -> {
+    //       System.out.println("42");
+    //     }
+    //     case Float f2 when f2 > 0 -> {
+    //       System.out.println("positif");
+    //     }
+    //     default -> {
+    //       System.out.println("negatif");
+    //     }
+    //   }
+    // }
+    //
+    // static void longSwitch(Long l) {
+    //   switch (l) {
+    //     case null -> {
+    //       System.out.println("null");
+    //     }
+    //     case 42L -> {
+    //       System.out.println("42");
+    //     }
+    //     case Long i2 when i2 > 0 -> {
+    //       System.out.println("positif");
+    //     }
+    //     default -> {
+    //       System.out.println("negatif");
+    //     }
+    //   }
+    // }
+
     static void intSwitch(Integer i) {
       switch (i) {
         case null -> {