/*
 * Copyright (c) 2019, the Dart 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.
 */
/**
 * @assertion If a map literal has a downwards inference type of Map<K, V> for
 * some K and V, then the downwards inference context type of the keys in the
 * body elements is K and the values is V.
 *
 * @description Checks that if a map literal has a downwards inference type of
 * Map<K, V> for some K and V, then the downwards inference context type of the
 * keys in the body elements is K and the values is V.
 * @author sgrekhov@unipro.ru
 */
// SharedOptions=--enable-experiment=constant-update-2018
import "../../Utils/expect.dart";

main() {
  Map<num, List<int>> map1 = {
    if (true) 11: [],
    if (false) 1: [] else 22: [],
    for (var i = 0; i < 1; i++) i: []
  };
  Expect.isTrue(map1 is Map<num, List<int>>);
  Expect.isFalse(map1 is Map<int, List<int>>);
  Expect.mapEquals({11: [], 22: [], 0: []}, map1);

  var map2 = <num, List<int>> {
    if (true) 11: [],
    if (false) 1: [] else 22: [],
    for (var i = 0; i < 1; i++) i: []
  };
  Expect.isTrue(map2 is Map<num, List<int>>);
  Expect.isFalse(map2 is Map<int, List<int>>);
  Expect.mapEquals({11: [], 22: [], 0: []}, map2);

  var map3 = const <num, List<int>> {
    if (true) 1: [],
    if (false) 2: [] else 3: [],
  };
  Expect.isTrue(map3 is Map<num, List<int>>);
  Expect.isFalse(map2 is Map<int, List<int>>);
  Expect.mapEquals({1: [], 3: []}, map3);

  const map4 = <num, List<int>> {
    if (true) 1: [],
    if (false) 2: [] else 3: [],
  };
  Expect.isTrue(map4 is Map<num, List<int>>);
  Expect.isFalse(map4 is Map<int, List<int>>);
  Expect.mapEquals({1: [], 3: []}, map4);
}
