[cfe] Iterate map entries in map spreads

There was a missing call to the getter Map.entries in the translation
of map spreads.  Fixes https://github.com/dart-lang/sdk/issues/36173

Change-Id: I211a61173c383f1c64032eb04491d03e4331cc9a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96780
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index d900fac..1afd831 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -53,6 +53,7 @@
   final Procedure setFactory;
   final Procedure setAdd;
   final Procedure objectEquals;
+  final Procedure mapEntries;
   final Procedure mapPut;
   final Class mapEntryClass;
   final Field mapEntryKey;
@@ -68,9 +69,11 @@
       : coreTypes = loader.coreTypes,
         listAdd = loader.coreTypes.index.getMember('dart:core', 'List', 'add'),
         setFactory = _findSetFactory(loader.coreTypes),
+        setAdd = loader.coreTypes.index.getMember('dart:core', 'Set', 'add'),
         objectEquals =
             loader.coreTypes.index.getMember('dart:core', 'Object', '=='),
-        setAdd = loader.coreTypes.index.getMember('dart:core', 'Set', 'add'),
+        mapEntries =
+            loader.coreTypes.index.getMember('dart:core', 'Map', 'get:entries'),
         mapPut = loader.coreTypes.index.getMember('dart:core', 'Map', '[]='),
         mapEntryClass =
             loader.coreTypes.index.getClass('dart:core', 'MapEntry'),
@@ -251,7 +254,7 @@
             new VariableDeclaration(null, type: mapEntryType, isFinal: true);
         Statement statement = new ForInStatement(
             elt,
-            value,
+            new PropertyGet(value, new Name('entries'), mapEntries),
             new ExpressionStatement(new MethodInvocation(
                 new VariableGet(map),
                 new Name('[]='),
diff --git a/pkg/front_end/testcases/spread_collection.dart.strong.expect b/pkg/front_end/testcases/spread_collection.dart.strong.expect
index 8ca66da..dbfd7b4 100644
--- a/pkg/front_end/testcases/spread_collection.dart.strong.expect
+++ b/pkg/front_end/testcases/spread_collection.dart.strong.expect
@@ -25,11 +25,11 @@
   final core::Map<core::int, core::int> aMap = block {
     final core::Map<core::int, core::int> #t5 = <core::int, core::int>{};
     #t5.{core::Map::[]=}(1, 1);
-    for (final core::MapEntry<core::int, core::int> #t6 in <core::int, core::int>{2: 2})
+    for (final core::MapEntry<core::int, core::int> #t6 in <core::int, core::int>{2: 2}.{core::Map::entries})
       #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
     final core::Map<dynamic, dynamic> #t7 = <core::int, core::int>{3: 3};
     if(!#t7.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t8 in #t7)
+      for (final core::MapEntry<core::int, core::int> #t8 in #t7.{core::Map::entries})
         #t5.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
   } =>#t5;
   final core::Set<core::int> aSet = block {
diff --git a/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect
index 8ca66da..dbfd7b4 100644
--- a/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect
@@ -25,11 +25,11 @@
   final core::Map<core::int, core::int> aMap = block {
     final core::Map<core::int, core::int> #t5 = <core::int, core::int>{};
     #t5.{core::Map::[]=}(1, 1);
-    for (final core::MapEntry<core::int, core::int> #t6 in <core::int, core::int>{2: 2})
+    for (final core::MapEntry<core::int, core::int> #t6 in <core::int, core::int>{2: 2}.{core::Map::entries})
       #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
     final core::Map<dynamic, dynamic> #t7 = <core::int, core::int>{3: 3};
     if(!#t7.{core::Object::==}(null))
-      for (final core::MapEntry<core::int, core::int> #t8 in #t7)
+      for (final core::MapEntry<core::int, core::int> #t8 in #t7.{core::Map::entries})
         #t5.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
   } =>#t5;
   final core::Set<core::int> aSet = block {
diff --git a/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect b/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
index b6afa97..fa9fa70 100644
--- a/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
@@ -124,12 +124,12 @@
   } =>#t3;
   core::Map<dynamic, dynamic> map10 = block {
     final core::Map<dynamic, dynamic> #t5 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic> #t6 in <dynamic, dynamic>{})
+    for (final core::MapEntry<dynamic, dynamic> #t6 in <dynamic, dynamic>{}.{core::Map::entries})
       #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
   } =>#t5;
   core::Map<dynamic, dynamic> map10ambiguous = block {
     final core::Map<dynamic, dynamic> #t7 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic> #t8 in <dynamic, dynamic>{})
+    for (final core::MapEntry<dynamic, dynamic> #t8 in <dynamic, dynamic>{}.{core::Map::entries})
       #t7.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
   } =>#t7;
   core::List<core::int> lhs20 = block {
@@ -150,13 +150,13 @@
   } =>#t13;
   core::Map<core::String, core::int> map20 = block {
     final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t16 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t16 in mapSpread.{core::Map::entries})
       #t15.{core::Map::[]=}(#t16.{core::MapEntry::key}, #t16.{core::MapEntry::value});
     #t15.{core::Map::[]=}("baz", 42);
   } =>#t15;
   core::Map<core::String, core::int> map20ambiguous = block {
     final core::Map<core::String, core::int> #t17 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t18 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t18 in mapSpread.{core::Map::entries})
       #t17.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
   } =>#t17;
   core::List<dynamic> lhs21 = block {
@@ -172,7 +172,7 @@
   } =>#t21;
   core::Map<dynamic, dynamic> map21 = block {
     final core::Map<dynamic, dynamic> #t23 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic> #t24 in (mapSpread as dynamic) as{TypeError} core::Map<dynamic, dynamic>)
+    for (final core::MapEntry<dynamic, dynamic> #t24 in ((mapSpread as dynamic) as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries})
       #t23.{core::Map::[]=}(#t24.{core::MapEntry::key}, #t24.{core::MapEntry::value});
     #t23.{core::Map::[]=}("baz", 42);
   } =>#t23;
@@ -198,7 +198,7 @@
   } =>#t29;
   core::Map<core::String, core::int> map22 = block {
     final core::Map<core::String, core::int> #t31 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t32 in <core::String, core::int>{})
+    for (final core::MapEntry<core::String, core::int> #t32 in <core::String, core::int>{}.{core::Map::entries})
       #t31.{core::Map::[]=}(#t32.{core::MapEntry::key}, #t32.{core::MapEntry::value});
   } =>#t31;
   core::List<core::List<core::int>> lhs23 = block {
@@ -219,7 +219,7 @@
   } =>#t37;
   core::Map<core::String, core::List<core::int>> map23 = block {
     final core::Map<core::String, core::List<core::int>> #t39 = <core::String, core::List<core::int>>{};
-    for (final core::MapEntry<core::String, core::List<core::int>> #t40 in <core::String, core::List<core::int>>{"baz": <core::int>[]})
+    for (final core::MapEntry<core::String, core::List<core::int>> #t40 in <core::String, core::List<core::int>>{"baz": <core::int>[]}.{core::Map::entries})
       #t39.{core::Map::[]=}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value});
   } =>#t39;
   dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:72:76: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
@@ -259,7 +259,7 @@
     {...mapSpread, \"baz\": 42};
     ^" in ( block {
     final core::Map<core::String, core::int> #t51 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t52 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t52 in mapSpread.{core::Map::entries})
       #t51.{core::Map::[]=}(#t52.{core::MapEntry::key}, #t52.{core::MapEntry::value});
     #t51.{core::Map::[]=}("baz", 42);
   } =>#t51) as{TypeError} core::int;
@@ -269,7 +269,7 @@
     {...mapSpread};
     ^" in ( block {
     final core::Map<core::String, core::int> #t54 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t55 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t55 in mapSpread.{core::Map::entries})
       #t54.{core::Map::[]=}(#t55.{core::MapEntry::key}, #t55.{core::MapEntry::value});
   } =>#t54) as{TypeError} core::int;
   core::List<dynamic> lhs40 = <dynamic>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:89:5: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
@@ -346,7 +346,7 @@
     final core::Map<core::String, core::int> #t76 = <core::String, core::int>{};
     final core::Map<dynamic, dynamic> #t77 = null;
     if(!#t77.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t78 in #t77)
+      for (final core::MapEntry<core::String, core::int> #t78 in #t77.{core::Map::entries})
         #t76.{core::Map::[]=}(#t78.{core::MapEntry::key}, #t78.{core::MapEntry::value});
   } =>#t76;
 }
diff --git a/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
index 3ba19f9..d9fbaef 100644
--- a/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
@@ -124,12 +124,12 @@
   } =>#t3;
   core::Map<dynamic, dynamic> map10 = block {
     final core::Map<dynamic, dynamic> #t5 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic> #t6 in <dynamic, dynamic>{})
+    for (final core::MapEntry<dynamic, dynamic> #t6 in <dynamic, dynamic>{}.{core::Map::entries})
       #t5.{core::Map::[]=}(#t6.{core::MapEntry::key}, #t6.{core::MapEntry::value});
   } =>#t5;
   core::Map<dynamic, dynamic> map10ambiguous = block {
     final core::Map<dynamic, dynamic> #t7 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic> #t8 in <dynamic, dynamic>{})
+    for (final core::MapEntry<dynamic, dynamic> #t8 in <dynamic, dynamic>{}.{core::Map::entries})
       #t7.{core::Map::[]=}(#t8.{core::MapEntry::key}, #t8.{core::MapEntry::value});
   } =>#t7;
   core::List<core::int> lhs20 = block {
@@ -150,13 +150,13 @@
   } =>#t13;
   core::Map<core::String, core::int> map20 = block {
     final core::Map<core::String, core::int> #t15 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t16 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t16 in mapSpread.{core::Map::entries})
       #t15.{core::Map::[]=}(#t16.{core::MapEntry::key}, #t16.{core::MapEntry::value});
     #t15.{core::Map::[]=}("baz", 42);
   } =>#t15;
   core::Map<core::String, core::int> map20ambiguous = block {
     final core::Map<core::String, core::int> #t17 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t18 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t18 in mapSpread.{core::Map::entries})
       #t17.{core::Map::[]=}(#t18.{core::MapEntry::key}, #t18.{core::MapEntry::value});
   } =>#t17;
   core::List<dynamic> lhs21 = block {
@@ -172,7 +172,7 @@
   } =>#t21;
   core::Map<dynamic, dynamic> map21 = block {
     final core::Map<dynamic, dynamic> #t23 = <dynamic, dynamic>{};
-    for (final core::MapEntry<dynamic, dynamic> #t24 in (mapSpread as dynamic) as{TypeError} core::Map<dynamic, dynamic>)
+    for (final core::MapEntry<dynamic, dynamic> #t24 in ((mapSpread as dynamic) as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries})
       #t23.{core::Map::[]=}(#t24.{core::MapEntry::key}, #t24.{core::MapEntry::value});
     #t23.{core::Map::[]=}("baz", 42);
   } =>#t23;
@@ -198,7 +198,7 @@
   } =>#t29;
   core::Map<core::String, core::int> map22 = block {
     final core::Map<core::String, core::int> #t31 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t32 in <core::String, core::int>{})
+    for (final core::MapEntry<core::String, core::int> #t32 in <core::String, core::int>{}.{core::Map::entries})
       #t31.{core::Map::[]=}(#t32.{core::MapEntry::key}, #t32.{core::MapEntry::value});
   } =>#t31;
   core::List<core::List<core::int>> lhs23 = block {
@@ -219,7 +219,7 @@
   } =>#t37;
   core::Map<core::String, core::List<core::int>> map23 = block {
     final core::Map<core::String, core::List<core::int>> #t39 = <core::String, core::List<core::int>>{};
-    for (final core::MapEntry<core::String, core::List<core::int>> #t40 in <core::String, core::List<core::int>>{"baz": <core::int>[]})
+    for (final core::MapEntry<core::String, core::List<core::int>> #t40 in <core::String, core::List<core::int>>{"baz": <core::int>[]}.{core::Map::entries})
       #t39.{core::Map::[]=}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value});
   } =>#t39;
   dynamic map24ambiguous = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:72:76: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
@@ -259,7 +259,7 @@
     {...mapSpread, \"baz\": 42};
     ^" in ( block {
     final core::Map<core::String, core::int> #t51 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t52 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t52 in mapSpread.{core::Map::entries})
       #t51.{core::Map::[]=}(#t52.{core::MapEntry::key}, #t52.{core::MapEntry::value});
     #t51.{core::Map::[]=}("baz", 42);
   } =>#t51) as{TypeError} core::int;
@@ -269,7 +269,7 @@
     {...mapSpread};
     ^" in ( block {
     final core::Map<core::String, core::int> #t54 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t55 in mapSpread)
+    for (final core::MapEntry<core::String, core::int> #t55 in mapSpread.{core::Map::entries})
       #t54.{core::Map::[]=}(#t55.{core::MapEntry::key}, #t55.{core::MapEntry::value});
   } =>#t54) as{TypeError} core::int;
   core::List<dynamic> lhs40 = <dynamic>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:89:5: Error: Unexpected type 'int' of a spread.  Expected 'dynamic' or an Iterable.
@@ -346,7 +346,7 @@
     final core::Map<core::String, core::int> #t76 = <core::String, core::int>{};
     final core::Map<dynamic, dynamic> #t77 = null;
     if(!#t77.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t78 in #t77)
+      for (final core::MapEntry<core::String, core::int> #t78 in #t77.{core::Map::entries})
         #t76.{core::Map::[]=}(#t78.{core::MapEntry::key}, #t78.{core::MapEntry::value});
   } =>#t76;
 }