Check exact type for set literals (issue 35742)

Change-Id: Icce758b13536171dd20201e52ecae8ecda39a336
Reviewed-on: https://dart-review.googlesource.com/c/91166
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3583fb3..c3f3647 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -579,6 +579,30 @@
   }
 
   @override
+  void visitSetLiteral(SetLiteral node) {
+    DartType type = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      NodeList<TypeAnnotation> targs = node.typeArguments.arguments;
+      if (targs.length > 0) {
+        type = targs[0].type;
+      }
+    } else {
+      DartType staticType = node.staticType;
+      if (staticType is InterfaceType) {
+        List<DartType> typeArguments = staticType.typeArguments;
+        if (typeArguments != null && typeArguments.length > 0) {
+          type = typeArguments[0];
+        }
+      }
+    }
+    NodeList<Expression> elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      checkArgument(elements[i], type);
+    }
+    super.visitSetLiteral(node);
+  }
+
+  @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     var element = node.staticElement;
     if (element != null) {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
new file mode 100644
index 0000000..125d43d
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
@@ -0,0 +1,71 @@
+// 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidCastNewExprTest);
+  });
+}
+
+@reflectiveTest
+class InvalidCastNewExprTest extends ResolverTestCase {
+  @override
+  List<String> get enabledExperiments => ['set-literals'];
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_listLiteral_const() async {
+    await assertErrorsInCode(r'''
+const c = <B>[A()];
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+
+  test_listLiteral_nonConst() async {
+    await assertErrorsInCode(r'''
+var c = <B>[A()];
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+
+  test_setLiteral_const() async {
+    await assertErrorsInCode(r'''
+const c = <B>{A()};
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+
+  test_setLiteral_nonConst() async {
+    await assertErrorsInCode(r'''
+var c = <B>{A()};
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 1a89283..20b7c10 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -9,6 +9,7 @@
 import 'deprecated_member_use_test.dart' as deprecated_member_use;
 import 'division_optimization_test.dart' as division_optimization;
 import 'invalid_assignment_test.dart' as invalid_assignment;
+import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr;
 import 'invalid_required_param_test.dart' as invalid_required_param;
 import 'undefined_getter.dart' as undefined_getter;
 import 'unnecessary_cast_test.dart' as unnecessary_cast;
@@ -25,6 +26,7 @@
     deprecated_member_use.main();
     division_optimization.main();
     invalid_assignment.main();
+    invalid_cast_new_expr.main();
     invalid_required_param.main();
     undefined_getter.main();
     unnecessary_cast.main();