Fix compat issue when removing and adding argument

Bug: b/346981583
Change-Id: Ic2c547ef8bf02bdfcf6b7d1b1b0b4d18d9f41e14
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 bd27dfc..d6216c3 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -35,7 +35,7 @@
 import com.android.tools.r8.graph.DexAnnotation.AnnotatedKind;
 import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.lens.GraphLens;
-import com.android.tools.r8.graph.proto.ArgumentInfoCollection;
+import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.NumericType;
 import com.android.tools.r8.ir.code.Position;
@@ -1579,13 +1579,16 @@
     }
 
     public Builder rewriteParameterAnnotations(
-        DexEncodedMethod method, ArgumentInfoCollection argumentInfoCollection) {
+        DexEncodedMethod method, RewrittenPrototypeDescription rewrittenPrototypeDescription) {
       if (parameterAnnotations.isEmpty()) {
         // Nothing to do.
         return this;
       }
+
+      var argumentInfoCollection = rewrittenPrototypeDescription.getArgumentInfoCollection();
       if (!argumentInfoCollection.hasArgumentPermutation()
-          && !argumentInfoCollection.hasRemovedArguments()) {
+          && !argumentInfoCollection.hasRemovedArguments()
+          && !rewrittenPrototypeDescription.hasExtraParameters()) {
         // Nothing to do.
         return this;
       }
@@ -1638,6 +1641,14 @@
         newNumberOfMissingParameterAnnotations = 0;
       }
 
+      if (rewrittenPrototypeDescription.hasExtraParameters()) {
+        for (int extraParameter = 0;
+            extraParameter < rewrittenPrototypeDescription.getExtraParameters().size();
+            extraParameter++) {
+          newParameterAnnotations.add(DexAnnotationSet.empty());
+        }
+      }
+
       return setParameterAnnotations(
           ParameterAnnotationsList.create(
               newParameterAnnotations.toArray(DexAnnotationSet.EMPTY_ARRAY),
diff --git a/src/main/java/com/android/tools/r8/graph/proto/ArgumentInfoCollection.java b/src/main/java/com/android/tools/r8/graph/proto/ArgumentInfoCollection.java
index 85ee2db..396f92d 100644
--- a/src/main/java/com/android/tools/r8/graph/proto/ArgumentInfoCollection.java
+++ b/src/main/java/com/android/tools/r8/graph/proto/ArgumentInfoCollection.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.graph.proto;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.lens.GraphLens;
 import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfoFixer;
@@ -24,7 +23,6 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Objects;
-import java.util.function.Consumer;
 
 public class ArgumentInfoCollection {
 
@@ -370,13 +368,4 @@
         RewrittenPrototypeDescription.create(Collections.emptyList(), null, this);
     return prototypeChanges.createMethodOptimizationInfoFixer();
   }
-
-  /**
-   * Returns a function for rewriting the parameter annotations on a method info after prototype
-   * changes were made.
-   */
-  public Consumer<DexEncodedMethod.Builder> createParameterAnnotationsRemover(
-      DexEncodedMethod method) {
-    return builder -> builder.rewriteParameterAnnotations(method, this);
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/proto/RewrittenPrototypeDescription.java b/src/main/java/com/android/tools/r8/graph/proto/RewrittenPrototypeDescription.java
index 67659b6..46d40d5 100644
--- a/src/main/java/com/android/tools/r8/graph/proto/RewrittenPrototypeDescription.java
+++ b/src/main/java/com/android/tools/r8/graph/proto/RewrittenPrototypeDescription.java
@@ -84,7 +84,7 @@
 
   public Consumer<DexEncodedMethod.Builder> createParameterAnnotationsRemover(
       DexEncodedMethod method) {
-    return getArgumentInfoCollection().createParameterAnnotationsRemover(method);
+    return builder -> builder.rewriteParameterAnnotations(method, this);
   }
 
   public MethodOptimizationInfoFixer createMethodOptimizationInfoFixer() {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithUnusedArgumentAndParameterAnnotations.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithUnusedArgumentAndParameterAnnotationsTest.java
similarity index 69%
rename from src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithUnusedArgumentAndParameterAnnotations.java
rename to src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithUnusedArgumentAndParameterAnnotationsTest.java
index e2d9f08..17b34b7 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithUnusedArgumentAndParameterAnnotations.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/CollisionWithUnusedArgumentAndParameterAnnotationsTest.java
@@ -3,14 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.optimize.unusedarguments;
 
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.NeverClassInline;
 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.StringUtils;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -23,7 +19,7 @@
 import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class CollisionWithUnusedArgumentAndParameterAnnotations extends TestBase {
+public class CollisionWithUnusedArgumentAndParameterAnnotationsTest extends TestBase {
 
   @Parameter(0)
   public TestParameters parameters;
@@ -50,25 +46,15 @@
 
   @Test
   public void testR8Compat() throws Exception {
-    try {
-      testForR8Compat(parameters.getBackend())
-          .addInnerClasses(getClass())
-          .addKeepMainRule(TestClass.class)
-          .addKeepRuntimeVisibleParameterAnnotations()
-          .addKeepClassAndMembersRules(ParameterAnnotation.class)
-          .setMinApi(parameters.getApiLevel())
-          .enableNeverClassInliningAnnotations()
-          .run(parameters.getRuntime(), TestClass.class)
-          .assertSuccessWithOutput(EXPECTED_OUTPUT);
-      assertTrue(
-          parameters.isDexRuntime()
-              && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.L));
-    } catch (CompilationFailedException e) {
-      // TODO(b/346981583): This should not hit an assertion.
-      assertTrue(
-          parameters.isCfRuntime() || parameters.getApiLevel().isLessThan(AndroidApiLevel.L));
-      assertTrue(e.getCause() instanceof AssertionError);
-    }
+    testForR8Compat(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(TestClass.class)
+        .addKeepRuntimeVisibleParameterAnnotations()
+        .addKeepClassAndMembersRules(ParameterAnnotation.class)
+        .setMinApi(parameters.getApiLevel())
+        .enableNeverClassInliningAnnotations()
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
   }
 
   @Retention(RetentionPolicy.RUNTIME)