Get rid of the clumsy while loop in inferInvocation.

See discussion in
https://dart-review.googlesource.com/c/sdk/+/29744/3/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart#892
Change-Id: I7b63269573749a61ff9e211d9df8676eae66b7e7
Reviewed-on: https://dart-review.googlesource.com/30000
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 861eb8b..aab2c19 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -42,7 +42,6 @@
         Member,
         MethodInvocation,
         Name,
-        NamedExpression,
         Procedure,
         ProcedureKind,
         PropertyGet,
@@ -907,11 +906,9 @@
     Substitution substitution;
     List<DartType> formalTypes;
     List<DartType> actualTypes;
-    List<Expression> expressions;
     if (inferenceNeeded || typeChecksNeeded) {
       formalTypes = [];
       actualTypes = [];
-      expressions = [];
     }
     if (inferenceNeeded) {
       if (isConst && typeContext != null) {
@@ -953,7 +950,6 @@
       if (inferenceNeeded || typeChecksNeeded) {
         formalTypes.add(formalType);
         actualTypes.add(expressionType);
-        expressions.add(expression);
       }
       if (isOverloadedArithmeticOperator) {
         returnType = typeSchemaEnvironment.getTypeOfOverloadedArithmetic(
@@ -976,21 +972,16 @@
       arguments.types.addAll(inferredTypes);
     }
     if (typeChecksNeeded) {
+      int numPositionalArgs = arguments.positional.length;
       for (int i = 0; i < formalTypes.length; i++) {
         var formalType = formalTypes[i];
         var expectedType = substitution != null
             ? substitution.substituteType(formalType)
             : formalType;
         var actualType = actualTypes[i];
-        var expression = expressions[i];
-        // If the expression was replaced during type inference, e.g. due
-        // to insertion of an Instantiation node, we need to find the replaced
-        // expression.  We can do so by walking parent pointers.
-        while (true) {
-          var parent = expression.parent;
-          if (identical(parent, arguments) || parent is NamedExpression) break;
-          expression = parent;
-        }
+        var expression = i < numPositionalArgs
+            ? arguments.positional[i]
+            : arguments.named[i - numPositionalArgs].value;
         checkAssignability(
             expectedType, actualType, expression, expression.fileOffset);
       }
diff --git a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect
index 22a2efc..205c40b 100644
--- a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect
@@ -9,6 +9,6 @@
   static method m({core::int a = 0}) → dynamic {}
 }
 static method test() → void {
-  self::C::m(a: const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/duplicated_named_args_3.dart:13:19: Error: Duplicated named argument 'a'.\n  C.m(a: 1, a: 2, a: 3);\n                  ^")));
+  self::C::m(a: const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/duplicated_named_args_3.dart:13:19: Error: Duplicated named argument 'a'.\n  C.m(a: 1, a: 2, a: 3);\n                  ^")) as{TypeError} core::int);
 }
 static method main() → dynamic {}