Revert "Custom conversion stubs"

This reverts commit 029ab7adda8a4936fc64a680fae7d4ff6209cc07.

Reason for revert: Failing InvokeStaticDesugarTest

Change-Id: Iae62756598b27a75766be73c4b555e2a82564a27
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
index 14c62be..cd8d6b7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
@@ -57,13 +57,6 @@
     return field;
   }
 
-  public CfFieldInstruction withField(DexField newField) {
-    if (field == newField) {
-      return this;
-    }
-    return new CfFieldInstruction(opcode, newField, newField);
-  }
-
   public int getOpcode() {
     return opcode;
   }
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index 3237f29..625430b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -77,13 +77,6 @@
     return method;
   }
 
-  public CfInvoke withMethod(DexMethod newMethod) {
-    if (method == newMethod) {
-      return this;
-    }
-    return new CfInvoke(opcode, newMethod, itf);
-  }
-
   public int getOpcode() {
     return opcode;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 4cf9a6f..c68adac 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1423,7 +1423,7 @@
     return new Builder(false);
   }
 
-  public static Builder builder(DexEncodedMethod from) {
+  private static Builder builder(DexEncodedMethod from) {
     return new Builder(from.isD8R8Synthesized(), from);
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
index 888707f..5d49406 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -53,9 +53,9 @@
       throws ExecutionException {
     List<DexProgramClass> classes = appView.appInfo().classes();
 
-    CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer =
-        new CfClassSynthesizerDesugaringEventConsumer();
-    converter.classSynthesisDesugaring(executorService, classSynthesizerEventConsumer);
+      CfClassSynthesizerDesugaringEventConsumer classSynthesizerEventConsumer =
+          new CfClassSynthesizerDesugaringEventConsumer();
+      converter.classSynthesisDesugaring(executorService, classSynthesizerEventConsumer);
     if (!classSynthesizerEventConsumer.getSynthesizedClasses().isEmpty()) {
       classes =
           ImmutableList.<DexProgramClass>builder()
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
index feb1b51..3f60ffe 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfClassSynthesizerDesugaringEventConsumer.java
@@ -4,10 +4,8 @@
 
 package com.android.tools.r8.ir.desugar;
 
-import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterL8SynthesizerEventConsumer;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryCustomConversionEventConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer;
 import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizerEventConsumer.L8ProgramEmulatedInterfaceSynthesizerEventConsumer;
 import com.android.tools.r8.ir.desugar.records.RecordDesugaringEventConsumer;
@@ -18,7 +16,6 @@
     implements L8ProgramEmulatedInterfaceSynthesizerEventConsumer,
         DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer,
         DesugaredLibraryRetargeterL8SynthesizerEventConsumer,
-        DesugaredLibraryCustomConversionEventConsumer,
         RecordDesugaringEventConsumer {
 
   private Set<DexProgramClass> synthesizedClasses = Sets.newConcurrentHashSet();
@@ -43,11 +40,6 @@
     synthesizedClasses.add(clazz);
   }
 
-  @Override
-  public void acceptCustomConversionClasspathClass(DexClasspathClass clazz) {
-    // Intentionally empty.
-  }
-
   public Set<DexProgramClass> getSynthesizedClasses() {
     return synthesizedClasses;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfCodeTypeRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/CfCodeTypeRewriter.java
deleted file mode 100644
index 8aa124c..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfCodeTypeRewriter.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.desugar;
-
-import com.android.tools.r8.cf.code.CfFieldInstruction;
-import com.android.tools.r8.cf.code.CfFrame;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.cf.code.CfInstruction;
-import com.android.tools.r8.cf.code.CfInvoke;
-import com.android.tools.r8.cf.code.CfTypeInstruction;
-import com.android.tools.r8.graph.CfCode;
-import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DexEncodedMethod;
-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.DexType;
-import com.android.tools.r8.utils.ListUtils;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Rewrites all references to a type in a CfCode instance to another type.
- *
- * <p>The implementation is minimal for the needs of DesugaredLibraryCustomConversionRewriter.
- */
-public class CfCodeTypeRewriter {
-
-  private final DexItemFactory factory;
-
-  public CfCodeTypeRewriter(DexItemFactory factory) {
-    this.factory = factory;
-  }
-
-  public DexEncodedMethod rewriteCfCode(
-      DexEncodedMethod method, Map<DexType, DexType> replacement) {
-    if (method.getCode() == null) {
-      assert false;
-      return null;
-    }
-    return DexEncodedMethod.builder(method)
-        .setMethod(rewriteMethod(method.getReference(), replacement))
-        .setCode(rewriteCfCode(method.getCode(), replacement))
-        .build();
-  }
-
-  private Code rewriteCfCode(Code code, Map<DexType, DexType> replacement) {
-    assert code.isCfCode();
-    CfCode cfCode = code.asCfCode();
-    List<CfInstruction> desugaredInstructions =
-        ListUtils.map(
-            cfCode.getInstructions(),
-            instruction -> rewriteCfInstruction(instruction, replacement));
-    cfCode.setInstructions(desugaredInstructions);
-    return cfCode;
-  }
-
-  private CfInstruction rewriteCfInstruction(
-      CfInstruction instruction, Map<DexType, DexType> replacement) {
-    if (instruction.isInvoke()) {
-      CfInvoke cfInvoke = instruction.asInvoke();
-      DexMethod replacementMethod = rewriteMethod(cfInvoke.getMethod(), replacement);
-      return cfInvoke.withMethod(replacementMethod);
-    }
-    if (instruction.isTypeInstruction()) {
-      CfTypeInstruction typeInstruction = instruction.asTypeInstruction();
-      return typeInstruction.withType(rewriteType(typeInstruction.getType(), replacement));
-    }
-    if (instruction.isFieldInstruction()) {
-      CfFieldInstruction fieldInstruction = instruction.asFieldInstruction();
-      DexField field = rewriteField(fieldInstruction.getField(), replacement);
-      return fieldInstruction.withField(field);
-    }
-    if (instruction.isFrame()) {
-      CfFrame cfFrame = instruction.asFrame();
-      return rewriteFrame(cfFrame, replacement);
-    }
-    assert !instruction.isInvokeDynamic();
-    return instruction;
-  }
-
-  private CfFrame rewriteFrame(CfFrame cfFrame, Map<DexType, DexType> replacement) {
-    Int2ReferenceAVLTreeMap<FrameType> newLocals = new Int2ReferenceAVLTreeMap<>();
-    cfFrame
-        .getLocals()
-        .forEach((i, frameType) -> newLocals.put(i, rewriteFrameType(frameType, replacement)));
-    Deque<FrameType> newStack = new ArrayDeque<>();
-    cfFrame
-        .getStack()
-        .forEach(frameType -> newStack.addLast(rewriteFrameType(frameType, replacement)));
-    return new CfFrame(newLocals, newStack);
-  }
-
-  private FrameType rewriteFrameType(FrameType frameType, Map<DexType, DexType> replacement) {
-    if (frameType.isInitialized()) {
-      return FrameType.initialized(rewriteType(frameType.getInitializedType(), replacement));
-    }
-    if (frameType.isUninitializedNew()) {
-      FrameType.uninitializedNew(
-          frameType.getUninitializedLabel(),
-          rewriteType(frameType.getUninitializedNewType(), replacement));
-    }
-    return frameType;
-  }
-
-  private DexType rewriteType(DexType type, Map<DexType, DexType> replacement) {
-    return replacement.getOrDefault(type, type);
-  }
-
-  private DexField rewriteField(DexField field, Map<DexType, DexType> replacement) {
-    DexType newHolder = rewriteType(field.holder, replacement);
-    DexType newType = rewriteType(field.type, replacement);
-    return factory.createField(newHolder, newType, field.name);
-  }
-
-  private DexMethod rewriteMethod(DexMethod reference, Map<DexType, DexType> replacement) {
-    DexType newHolder = rewriteType(reference.holder, replacement);
-    DexType newReturnType = rewriteType(reference.getReturnType(), replacement);
-    DexType[] newParameters = new DexType[reference.getArity()];
-    for (int i = 0; i < reference.getArity(); i++) {
-      newParameters[i] = rewriteType(reference.getParameter(i), replacement);
-    }
-    return factory.createMethod(
-        newHolder, factory.createProto(newReturnType, newParameters), reference.getName());
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index 39d072a..2493dd3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -100,11 +100,6 @@
       }
 
       @Override
-      public void acceptCustomConversionClasspathClass(DexClasspathClass clazz) {
-        assert false;
-      }
-
-      @Override
       public void acceptAPIConversion(ProgramMethod method) {
         assert false;
       }
@@ -287,11 +282,6 @@
     }
 
     @Override
-    public void acceptCustomConversionClasspathClass(DexClasspathClass clazz) {
-      // Intentionally empty.
-    }
-
-    @Override
     public void acceptAPIConversion(ProgramMethod method) {
       methodProcessor.scheduleDesugaredMethodForProcessing(method);
     }
@@ -446,11 +436,6 @@
     }
 
     @Override
-    public void acceptCustomConversionClasspathClass(DexClasspathClass clazz) {
-      additions.addLiveClasspathClass(clazz);
-    }
-
-    @Override
     public void acceptAPIConversion(ProgramMethod method) {
       // Intentionally empty. The method will be hit by tracing if required.
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
index 486915a..8f5178e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
@@ -118,11 +118,6 @@
     public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
       // Intentionally empty.
     }
-
-    @Override
-    public void acceptCustomConversionClasspathClass(DexClasspathClass clazz) {
-      // Intentionally empty.
-    }
   }
 
   public static class R8PostProcessingDesugaringEventConsumer
@@ -196,10 +191,5 @@
     public void acceptWrapperClasspathClass(DexClasspathClass clazz) {
       additions.addLiveClasspathClass(clazz);
     }
-
-    @Override
-    public void acceptCustomConversionClasspathClass(DexClasspathClass clazz) {
-      additions.addLiveClasspathClass(clazz);
-    }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryCustomConversionRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryCustomConversionRewriter.java
deleted file mode 100644
index 2a800f8..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryCustomConversionRewriter.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.ir.desugar.desugaredlibrary;
-
-import static com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAPIConverter.vivifiedTypeFor;
-import static com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizer.conversionEncodedMethod;
-
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexMethod;
-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.ir.desugar.CfClassSynthesizerDesugaring;
-import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfCodeTypeRewriter;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryCustomConversionEventConsumer;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * L8 specific pass, rewrites or generates custom conversions.
- *
- * <p>In normal set-ups, custom conversions are provided with the types: type <-> rewrittenType.
- * However the compiler uses internally the types: vivifiedType <-> type during compilation. This
- * pass rewrites the custom conversions from type <-> rewrittenType to vivifiedType <-> type so the
- * compilation can look-up and find the methods.
- *
- * <p>In broken set-ups, where the input is missing, instead generates the custom conversions on the
- * classpath since they are assumed to be present in L8.
- */
-public class DesugaredLibraryCustomConversionRewriter implements CfClassSynthesizerDesugaring {
-
-  private final AppView<?> appView;
-  private final DesugaredLibraryWrapperSynthesizer synthesizer;
-  private final DexString libraryPrefix;
-
-  public DesugaredLibraryCustomConversionRewriter(
-      AppView<?> appView, DesugaredLibraryWrapperSynthesizer synthesizer) {
-    assert appView.options().isDesugaredLibraryCompilation();
-    this.appView = appView;
-    this.synthesizer = synthesizer;
-    this.libraryPrefix =
-        appView
-            .dexItemFactory()
-            .createString(
-                "L"
-                    + appView
-                        .options()
-                        .desugaredLibraryConfiguration
-                        .getSynthesizedLibraryClassesPackagePrefix());
-  }
-
-  @Override
-  public void synthesizeClasses(CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
-    Map<DexProgramClass, Set<DexEncodedMethod>> methodsToProcessPerClass =
-        readConversionMethodsToConvert(eventConsumer);
-    methodsToProcessPerClass.forEach(
-        (conversionHolder, conversionsMethods) -> {
-          Set<DexEncodedMethod> convertedMethods = convertMethods(conversionsMethods);
-          conversionHolder.getMethodCollection().removeMethods(conversionsMethods);
-          conversionHolder.addDirectMethods(convertedMethods);
-        });
-  }
-
-  private Map<DexProgramClass, Set<DexEncodedMethod>> readConversionMethodsToConvert(
-      DesugaredLibraryCustomConversionEventConsumer eventConsumer) {
-    Map<DexProgramClass, Set<DexEncodedMethod>> methodsToProcessPerClass = new IdentityHashMap<>();
-    appView
-        .options()
-        .desugaredLibraryConfiguration
-        .getCustomConversions()
-        .forEach(
-            (convertedType, conversionHolder) -> {
-              DexClass dexClass = appView.definitionFor(conversionHolder);
-              if (dexClass == null || dexClass.isNotProgramClass()) {
-                generateMissingConversion(eventConsumer, convertedType, conversionHolder);
-                return;
-              }
-              DexProgramClass conversionProgramClass = dexClass.asProgramClass();
-              DexType rewrittenType = appView.rewritePrefix.rewrittenType(convertedType, appView);
-              Set<DexEncodedMethod> methods =
-                  methodsToProcessPerClass.computeIfAbsent(
-                      conversionProgramClass, ignored -> Sets.newIdentityHashSet());
-              methods.add(
-                  conversionEncodedMethod(
-                      conversionProgramClass,
-                      rewrittenType,
-                      convertedType,
-                      appView.dexItemFactory()));
-              methods.add(
-                  conversionEncodedMethod(
-                      conversionProgramClass,
-                      convertedType,
-                      rewrittenType,
-                      appView.dexItemFactory()));
-            });
-    return methodsToProcessPerClass;
-  }
-
-  private void generateMissingConversion(
-      DesugaredLibraryCustomConversionEventConsumer eventConsumer,
-      DexType convertedType,
-      DexType conversionHolder) {
-    appView
-        .options()
-        .reporter
-        .warning(
-            "Missing custom conversion "
-                + conversionHolder
-                + " from L8 compilation: Cannot convert "
-                + convertedType);
-    DexType vivifiedType = vivifiedTypeFor(convertedType, appView);
-    synthesizer.ensureClasspathCustomConversion(
-        vivifiedType, convertedType, eventConsumer, conversionHolder);
-    synthesizer.ensureClasspathCustomConversion(
-        convertedType, vivifiedType, eventConsumer, conversionHolder);
-  }
-
-  private Set<DexEncodedMethod> convertMethods(Set<DexEncodedMethod> conversionsMethods) {
-    Set<DexEncodedMethod> newMethods = Sets.newIdentityHashSet();
-    CfCodeTypeRewriter cfCodeTypeRewriter = new CfCodeTypeRewriter(appView.dexItemFactory());
-    for (DexEncodedMethod conversionMethod : conversionsMethods) {
-      Map<DexType, DexType> replacement = computeReplacement(conversionMethod.getReference());
-      newMethods.add(cfCodeTypeRewriter.rewriteCfCode(conversionMethod, replacement));
-    }
-    return newMethods;
-  }
-
-  private Map<DexType, DexType> computeReplacement(DexMethod reference) {
-    assert reference.getArity() == 1;
-    DexType argumentType = reference.getArgumentType(0, true);
-    if (isLibraryPrefixed(argumentType)) {
-      return ImmutableMap.of(
-          argumentType,
-          convertDesugaredLibraryToVivifiedType(argumentType, reference.getReturnType()));
-    }
-    assert isLibraryPrefixed(reference.getReturnType());
-    return ImmutableMap.of(
-        reference.getReturnType(),
-        convertDesugaredLibraryToVivifiedType(reference.getReturnType(), argumentType));
-  }
-
-  private boolean isLibraryPrefixed(DexType argumentType) {
-    return argumentType.getDescriptor().startsWith(libraryPrefix);
-  }
-
-  private DexType convertDesugaredLibraryToVivifiedType(DexType type, DexType oppositeType) {
-    if (!isLibraryPrefixed(type)) {
-      return type;
-    }
-    return vivifiedTypeFor(oppositeType, appView);
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java
index d1b1546..9bc1a8e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizer.java
@@ -10,7 +10,6 @@
 import com.android.tools.r8.graph.ClasspathOrLibraryClass;
 import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
@@ -25,7 +24,6 @@
 import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaring;
 import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryClasspathWrapperSynthesizeEventConsumer;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryCustomConversionEventConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer;
 import com.android.tools.r8.ir.synthetic.DesugaredLibraryAPIConversionCfCodeProvider.APIConverterConstructorCfCodeProvider;
 import com.android.tools.r8.ir.synthetic.DesugaredLibraryAPIConversionCfCodeProvider.APIConverterThrowRuntimeExceptionCfCodeProvider;
@@ -124,28 +122,13 @@
       DexType srcType,
       DexType destType,
       DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer) {
-    if (hasCustomConversion(type)) {
-      return getCustomConversion(type, srcType, destType, eventConsumer);
+    DexMethod customConversion = getCustomConversion(type, srcType, destType);
+    if (customConversion != null) {
+      return customConversion;
     }
     assert canGenerateWrapper(type) : type;
-    WrapperConversions wrapperConversions =
-        ensureWrappers(getValidClassToWrap(type), eventConsumer);
-    return extractConversion(type, srcType, destType, wrapperConversions);
-  }
-
-  public DexMethod getExistingProgramConversionMethod(
-      DexType type, DexType srcType, DexType destType) {
-    if (hasCustomConversion(type)) {
-      return getExistingProgramCustomConversion(type, srcType, destType);
-    }
-    assert canGenerateWrapper(type) : type;
-    WrapperConversions wrapperConversions =
-        getExistingProgramWrapperConversions(getValidClassToWrap(type));
-    return extractConversion(type, srcType, destType, wrapperConversions);
-  }
-
-  private DexMethod extractConversion(
-      DexType type, DexType srcType, DexType destType, WrapperConversions wrapperConversions) {
+    DexClass clazz = getValidClassToWrap(type);
+    WrapperConversions wrapperConversions = ensureWrappers(clazz, eventConsumer);
     DexMethod conversion =
         type == srcType
             ? wrapperConversions.getConversion()
@@ -155,80 +138,32 @@
     return conversion;
   }
 
-  private boolean hasCustomConversion(DexType type) {
-    return appView.options().desugaredLibraryConfiguration.getCustomConversions().get(type) != null;
-  }
-
-  private DexMethod getCustomConversion(
-      DexType type,
-      DexType srcType,
-      DexType destType,
-      DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer) {
-    assert hasCustomConversion(type);
-    DexType conversionHolder =
-        appView.options().desugaredLibraryConfiguration.getCustomConversions().get(type);
-    assert conversionHolder != null;
-    DexClass dexClass = appView.definitionFor(conversionHolder);
-    if (dexClass != null && dexClass.isProgramClass()) {
-      return getExistingProgramCustomConversion(type, srcType, destType);
-    }
-    return ensureClasspathCustomConversion(srcType, destType, eventConsumer, conversionHolder)
-        .getReference();
-  }
-
-  public DexClassAndMethod ensureClasspathCustomConversion(
-      DexType srcType,
-      DexType destType,
-      DesugaredLibraryCustomConversionEventConsumer eventConsumer,
-      DexType conversionHolder) {
-    return appView
-        .getSyntheticItems()
-        .ensureFixedClasspathClassFromTypeMethod(
-            factory.convertMethodName,
-            factory.createProto(destType, srcType),
-            SyntheticKind.CUSTOM_CONVERSION,
-            conversionHolder,
-            appView,
-            ignored -> {},
-            eventConsumer::acceptCustomConversionClasspathClass,
-            methodBuilder ->
-                methodBuilder
-                    .setAccessFlags(
-                        MethodAccessFlags.fromSharedAccessFlags(
-                            Constants.ACC_PUBLIC | Constants.ACC_STATIC, false))
-                    .setCode(null));
-  }
-
-  private DexMethod getExistingProgramCustomConversion(
+  public DexMethod getExistingProgramConversionMethod(
       DexType type, DexType srcType, DexType destType) {
-    assert hasCustomConversion(type);
+    DexMethod customConversion = getCustomConversion(type, srcType, destType);
+    if (customConversion != null) {
+      return customConversion;
+    }
+    WrapperConversions wrapperConversions =
+        getExistingProgramWrapperConversions(getValidClassToWrap(type));
+    DexMethod conversion =
+        type == srcType
+            ? wrapperConversions.getConversion()
+            : wrapperConversions.getVivifiedConversion();
+    assert srcType == conversion.getArgumentType(0, true);
+    return conversion;
+  }
+
+  private DexMethod getCustomConversion(DexType type, DexType srcType, DexType destType) {
+    // ConversionType holds the methods "rewrittenType convert(type)" and the other way around.
+    // But everything is going to be rewritten, so we need to use vivifiedType and type".
     DexType conversionHolder =
         appView.options().desugaredLibraryConfiguration.getCustomConversions().get(type);
-    assert conversionHolder != null;
-    DexClass dexClass = appView.definitionFor(conversionHolder);
-    assert dexClass != null;
-    // Note: DexClass can unfortunately be a non program class on broken set-ups.
-    DexMethod conversionMethod =
-        conversionMethod(dexClass.type, srcType, destType, appView.dexItemFactory());
-    assert conversionEncodedMethod(dexClass, srcType, destType, appView.dexItemFactory())
-            .getReference()
-        == conversionMethod;
-    return conversionMethod;
-  }
-
-  public static DexEncodedMethod conversionEncodedMethod(
-      DexClass conversionHolder, DexType srcType, DexType destType, DexItemFactory factory) {
-    DexMethod method = conversionMethod(conversionHolder.type, srcType, destType, factory);
-    DexEncodedMethod conversionMethod = conversionHolder.lookupDirectMethod(method);
-    assert conversionMethod != null;
-    return conversionMethod;
-  }
-
-  private static DexMethod conversionMethod(
-      DexType conversionHolder, DexType srcType, DexType destType, DexItemFactory factory) {
-    DexProto proto = factory.createProto(destType, srcType);
-    DexMethod method = factory.createMethod(conversionHolder, proto, factory.convertMethodName);
-    return method;
+    if (conversionHolder != null) {
+      return factory.createMethod(
+          conversionHolder, factory.createProto(destType, srcType), factory.convertMethodName);
+    }
+    return null;
   }
 
   private boolean canConvert(DexType type) {
@@ -339,12 +274,10 @@
   }
 
   private DexMethod getConversion(DexClass wrapper, DexType returnType, DexType argType) {
-    DexMethod conversionMethod =
-        conversionMethod(wrapper.type, argType, returnType, appView.dexItemFactory());
-    assert conversionEncodedMethod(wrapper, argType, returnType, appView.dexItemFactory())
-            .getReference()
-        == conversionMethod;
-    return conversionMethod;
+    DexMethod convertMethod =
+        factory.createMethod(
+            wrapper.type, factory.createProto(returnType, argType), factory.convertMethodName);
+    return wrapper.lookupDirectMethod(convertMethod).getReference();
   }
 
   private DexEncodedField getWrapperUniqueEncodedField(DexClass wrapper) {
@@ -697,7 +630,6 @@
   @Override
   public void synthesizeClasses(CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
     DesugaredLibraryConfiguration conf = appView.options().desugaredLibraryConfiguration;
-    new DesugaredLibraryCustomConversionRewriter(appView, this).synthesizeClasses(eventConsumer);
     List<DexProgramClass> validClassesToWrap = new ArrayList<>();
     for (DexType type : conf.getWrapperConversions()) {
       assert !conf.getCustomConversions().containsKey(type);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizerEventConsumer.java
index a4a894d..212ad66 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryWrapperSynthesizerEventConsumer.java
@@ -15,13 +15,7 @@
     void acceptWrapperProgramClass(DexProgramClass clazz);
   }
 
-  interface DesugaredLibraryCustomConversionEventConsumer {
-
-    void acceptCustomConversionClasspathClass(DexClasspathClass clazz);
-  }
-
-  interface DesugaredLibraryClasspathWrapperSynthesizeEventConsumer
-      extends DesugaredLibraryCustomConversionEventConsumer {
+  interface DesugaredLibraryClasspathWrapperSynthesizeEventConsumer {
 
     void acceptWrapperClasspathClass(DexClasspathClass clazz);
   }
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 f136195..7dc9de3 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
@@ -165,6 +165,7 @@
     DesugaredLibraryConfiguration config = options.desugaredLibraryConfiguration;
     BiConsumer<DexType, DexType> registerEntry = registerMapEntry(appInfo);
     config.getEmulateLibraryInterface().forEach(registerEntry);
+    config.getCustomConversions().forEach(registerEntry);
     config.getRetargetCoreLibMember().forEach((method, types) -> types.forEach(registerEntry));
   }
 
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 9e362ed..474d1c3 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -644,86 +644,31 @@
       AppView<?> appView,
       Consumer<SyntheticClasspathClassBuilder> classConsumer,
       Consumer<DexClasspathClass> onCreationConsumer) {
-    // Obtain the outer synthesizing context in the case the context itself is synthetic.
-    // This is to ensure a flat input-type -> synthetic-item mapping.
     SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
     DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
-    return internalEnsureDexClasspathClass(
-        kind, classConsumer, onCreationConsumer, outerContext, type, appView);
-  }
-
-  private DexClasspathClass internalEnsureDexClasspathClass(
-      SyntheticKind kind,
-      Consumer<SyntheticClasspathClassBuilder> classConsumer,
-      Consumer<DexClasspathClass> onCreationConsumer,
-      SynthesizingContext outerContext,
-      DexType type,
-      AppView<?> appView) {
     DexClass dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
     if (dexClass != null) {
       assert dexClass.isClasspathClass();
       return dexClass.asClasspathClass();
     }
-    synchronized (type) {
+    synchronized (context) {
       dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
       if (dexClass != null) {
         assert dexClass.isClasspathClass();
         return dexClass.asClasspathClass();
       }
-      DexClasspathClass clazz =
-          internalCreateClasspathClass(
-              kind, classConsumer, outerContext, type, appView.dexItemFactory());
+      // Obtain the outer synthesizing context in the case the context itself is synthetic.
+      // This is to ensure a flat input-type -> synthetic-item mapping.
+      SyntheticClasspathClassBuilder classBuilder =
+          new SyntheticClasspathClassBuilder(type, kind, outerContext, appView.dexItemFactory());
+      classConsumer.accept(classBuilder);
+      DexClasspathClass clazz = classBuilder.build();
+      addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
       onCreationConsumer.accept(clazz);
       return clazz;
     }
   }
 
-  private DexClasspathClass internalCreateClasspathClass(
-      SyntheticKind kind,
-      Consumer<SyntheticClasspathClassBuilder> fn,
-      SynthesizingContext outerContext,
-      DexType type,
-      DexItemFactory factory) {
-    SyntheticClasspathClassBuilder classBuilder =
-        new SyntheticClasspathClassBuilder(type, kind, outerContext, factory);
-    fn.accept(classBuilder);
-      DexClasspathClass clazz = classBuilder.build();
-      addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
-      return clazz;
-    }
-
-  public DexClasspathClass ensureFixedClasspathClassFromType(
-      SyntheticKind kind,
-      DexType contextType,
-      AppView<?> appView,
-      Consumer<SyntheticClasspathClassBuilder> classConsumer,
-      Consumer<DexClasspathClass> onCreationConsumer) {
-    SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
-    DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
-    return internalEnsureDexClasspathClass(
-        kind, classConsumer, onCreationConsumer, outerContext, type, appView);
-  }
-
-  public DexClassAndMethod ensureFixedClasspathClassFromTypeMethod(
-      DexString methodName,
-      DexProto methodProto,
-      SyntheticKind kind,
-      DexType contextType,
-      AppView<?> appView,
-      Consumer<SyntheticClasspathClassBuilder> classConsumer,
-      Consumer<DexClasspathClass> onCreationConsumer,
-      Consumer<SyntheticMethodBuilder> buildMethodCallback) {
-    DexClasspathClass clazz =
-        ensureFixedClasspathClassFromType(
-            kind, contextType, appView, classConsumer, onCreationConsumer);
-    DexMethod methodReference =
-        appView.dexItemFactory().createMethod(clazz.getType(), methodProto, methodName);
-    DexEncodedMethod methodDefinition =
-        internalEnsureMethod(
-            methodReference, clazz, kind, appView, buildMethodCallback, emptyConsumer());
-    return DexClassAndMethod.create(clazz, methodDefinition);
-  }
-
   public DexClassAndMethod ensureFixedClasspathClassMethod(
       DexString methodName,
       DexProto methodProto,
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
index 567b595..0e45bd8 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
@@ -157,10 +157,6 @@
   }
 
   private Code getCodeObject(DexMethod methodSignature) {
-    if (codeGenerator == null) {
-      // The codeGenerator may be null on classpath classes.
-      return null;
-    }
     return codeGenerator.generate(methodSignature);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index 872fdee..0a05c0f 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -28,7 +28,6 @@
     ENUM_UNBOXING_LOCAL_UTILITY_CLASS("$EnumUnboxingLocalUtility", 24, false, true),
     ENUM_UNBOXING_SHARED_UTILITY_CLASS("$EnumUnboxingSharedUtility", 25, false, true),
     RECORD_TAG("", 1, false, true, true),
-    CUSTOM_CONVERSION("", 31, false, true),
     COMPANION_CLASS("$-CC", 2, false, true),
     EMULATED_INTERFACE_CLASS("$-EL", 3, false, true),
     RETARGET_CLASS("RetargetClass", 20, false, true),