[Kernel] Add list of unused arguments to InstanceCreation nodes.

During constant evaluation, unused arguments to a const constructor are
thrown away after evaluation, since their values do not affect the
resulting instance constant. If such an unused argument ends up
unevaluated, any errors that would arise in the final evaluation are
not reported.

This CL adds space in the Kernel AST for saving these unevaluated
expressions so they can be checked during final constant evaluation.

Even though this is an incompatible change, no update is needed to the
VM code (except for the version bump), since the VM does not support
InstanceCreation nodes in the first place.

Change-Id: I4752562c1164efbba79eb018c15b07ed8354ce5f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105761
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index b015270..d334dac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2139,8 +2139,9 @@
     fields.forEach((Field field, Constant value) {
       fieldValues[field.reference] = evaluator.extract(value);
     });
+    // TODO(askesc): Put actual unused arguments.
     return new InstanceCreation(
-        klass.reference, typeArguments, fieldValues, asserts);
+        klass.reference, typeArguments, fieldValues, asserts, []);
   }
 }
 
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 6b247af..9dc8a27 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -139,7 +139,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 25;
+  UInt32 formatVersion = 26;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
   UriSource sourceMap;
@@ -730,6 +730,7 @@
   List<DartType> typeArguments;
   List<[FieldReference, Expression]> fieldValues;
   List<AssertStatement> asserts;
+  List<Expression> unusedArguments;
 }
 
 type IsExpression extends Expression {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 7b3407fb..0ff11cf 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3330,17 +3330,18 @@
 /// Create an instance directly from the field values.
 ///
 /// This expression arises from const constructor calls when one or more field
-/// initializing expressions, field initializers or assert initializers contain
-/// unevaluated expressions. They only ever occur within unevaluated constants
-/// in constant expressions.
+/// initializing expressions, field initializers, assert initializers or unused
+/// arguments contain unevaluated expressions. They only ever occur within
+/// unevaluated constants in constant expressions.
 class InstanceCreation extends Expression {
   final Reference classReference;
   final List<DartType> typeArguments;
   final Map<Reference, Expression> fieldValues;
   final List<AssertStatement> asserts;
+  final List<Expression> unusedArguments;
 
-  InstanceCreation(
-      this.classReference, this.typeArguments, this.fieldValues, this.asserts);
+  InstanceCreation(this.classReference, this.typeArguments, this.fieldValues,
+      this.asserts, this.unusedArguments);
 
   Class get classNode => classReference.asClass;
 
@@ -3363,6 +3364,7 @@
       value.accept(v);
     }
     visitList(asserts, v);
+    visitList(unusedArguments, v);
   }
 
   transformChildren(Transformer v) {
@@ -3374,6 +3376,7 @@
       }
     });
     transformList(asserts, v, this);
+    transformList(unusedArguments, v, this);
   }
 }
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 905363a..f1996a9 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1592,8 +1592,9 @@
         for (int i = 0; i < assertCount; i++) {
           asserts[i] = readStatement();
         }
-        return new InstanceCreation(
-            classReference, typeArguments, fieldValues, asserts)
+        List<Expression> unusedArguments = readExpressionList();
+        return new InstanceCreation(classReference, typeArguments, fieldValues,
+            asserts, unusedArguments)
           ..fileOffset = offset;
       case Tag.IsExpression:
         int offset = readOffset();
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 0292314..35337ea 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1544,6 +1544,7 @@
       writeNode(value);
     });
     writeNodeList(node.asserts);
+    writeNodeList(node.unusedArguments);
   }
 
   @override
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index d5f1940..2c7df60 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -214,7 +214,8 @@
         node.classReference,
         node.typeArguments.map(visitType).toList(),
         fieldValues,
-        node.asserts.map(clone).toList());
+        node.asserts.map(clone).toList(),
+        node.unusedArguments.map(clone).toList());
   }
 
   visitIsExpression(IsExpression node) {
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 5862b83..4578819 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1330,6 +1330,14 @@
         writeExpression(assert_.message);
       }
       write(')');
+      first = false;
+    }
+    for (Expression unusedArgument in node.unusedArguments) {
+      if (!first) {
+        writeComma();
+      }
+      writeExpression(unusedArgument);
+      first = false;
     }
 
     write('}');
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 760c6ac..8b99273 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
 
 // Both version numbers are inclusive.
 static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 25;
+static const uint32_t kMaxSupportedKernelFormatVersion = 26;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \