Version 2.16.0-2.0.dev

Merge commit 'ac78f998830e08e82f47095ae3c5c9b30e7444db' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 4281850..a988d58 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-10-26T10:20:01.277340",
+  "generated": "2021-11-10T09:58:01.876670",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -124,7 +124,7 @@
       "name": "bazel_worker",
       "rootUri": "../third_party/pkg/bazel_worker",
       "packageUri": "lib/",
-      "languageVersion": "2.12"
+      "languageVersion": "2.14"
     },
     {
       "name": "benchmark_harness",
diff --git a/DEPS b/DEPS
index 8c0e608..e93a12b 100644
--- a/DEPS
+++ b/DEPS
@@ -76,7 +76,7 @@
   # Revisions of /third_party/* dependencies.
   "args_rev": "3b3f55766af13d895d2020ec001a28e8dc147f91",
   "async_rev": "80886150a5e6c58006c8ae5a6c2aa7108638e2a9",
-  "bazel_worker_rev": "0885637b037979afbf5bcd05fd748b309fd669c0",
+  "bazel_worker_rev": "ceeba0982d4ff40d32371c9d35f3d2dc1868de20",
   "benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
   "boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
   "boringssl_gen_rev": "7322fc15cc065d8d2957fccce6b62a509dc4d641",
@@ -141,7 +141,7 @@
   "process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
   "protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
   "pub_rev": "96404e0749864c9fbf8b12e1d424e8078809e00a",
-  "pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
+  "pub_semver_rev": "cee044a3dc867c1c8464408ed435bd21949510c0",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
   "shelf_static_rev": "202ec1a53c9a830c17cf3b718d089cf7eba568ad",
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 96389a0..56442ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -239,10 +239,6 @@
 
   final AstNode node;
 
-  /// A map keyed by lock names whose value is a list of the ranges for which a
-  /// lock has already been acquired.
-  final Map<String, List<SourceRange>> _lockRanges = {};
-
   CorrectionProducerContext._({
     required this.resolvedResult,
     required this.workspace,
@@ -458,26 +454,6 @@
 
   CorrectionUtils get utils => _context.utils;
 
-  /// Return `true` if this is the first request to lock the given [range] for
-  /// the lock with the given [lockName], or false if a lock for that range has
-  /// already been acquired.
-  ///
-  /// This method is used to allow correction producers to guard against
-  /// repeating changes that have already been made. For example, if multiple
-  /// arguments in an argument list have diagnostics reported against them and
-  /// the fix will fix all of the arguments, then the fix should be applied for
-  /// the first diagnostic and not for the others. A correction producer can
-  /// ensure this behavior by attempting to acquire a lock prior to creating any
-  /// edits, and only create the edits if a lock could be acquired.
-  bool acquireLockOnRange(String lockName, SourceRange range) {
-    var ranges = _context._lockRanges.putIfAbsent(lockName, () => []);
-    if (ranges.contains(range)) {
-      return false;
-    }
-    ranges.add(range);
-    return true;
-  }
-
   /// Configure this producer based on the [context].
   void configure(CorrectionProducerContext context) {
     _context = context;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 6ea735c..c71ea13 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -59,9 +59,6 @@
       // This should only happen if `validate` didn't check this case.
       return;
     }
-    if (!fix.acquireLockOnRange('ModifyParameters', range.node(argumentList))) {
-      return;
-    }
     var arguments = argumentList.arguments;
     var argumentCount = arguments.length;
     var templateContext = TemplateContext(invocation, fix.utils);
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 319ddc6..6376bc1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -221,11 +221,13 @@
 
     _typeSystemLegacy?.updateOptions(
       implicitCasts: analysisOptions.implicitCasts,
+      strictCasts: analysisOptions.strictCasts,
       strictInference: analysisOptions.strictInference,
     );
 
     _typeSystemNonNullableByDefault?.updateOptions(
       implicitCasts: analysisOptions.implicitCasts,
+      strictCasts: analysisOptions.strictCasts,
       strictInference: analysisOptions.strictInference,
     );
   }
@@ -268,6 +270,7 @@
     _typeSystemLegacy = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: false,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: legacy,
     );
@@ -275,6 +278,7 @@
     _typeSystemNonNullableByDefault = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: true,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: nonNullableByDefault,
     );
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 094b8b6..313caf6 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -518,6 +518,7 @@
     var typeSystem = TypeSystemImpl(
       implicitCasts: false,
       isNonNullableByDefault: false,
+      strictCasts: false,
       strictInference: false,
       typeProvider: typeProvider,
     );
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index ef329f4..b38a654 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -45,6 +45,11 @@
   /// This affects the behavior of [isAssignableTo].
   bool implicitCasts;
 
+  /// True if "strict casts" should be enforced.
+  ///
+  /// This affects the behavior of [isAssignableTo].
+  bool strictCasts;
+
   /// A flag indicating whether inference failures are allowed, off by default.
   ///
   /// This option is experimental and subject to change.
@@ -71,6 +76,7 @@
   TypeSystemImpl({
     required this.implicitCasts,
     required this.isNonNullableByDefault,
+    required this.strictCasts,
     required this.strictInference,
     required TypeProvider typeProvider,
   }) : typeProvider = typeProvider as TypeProviderImpl {
@@ -699,9 +705,10 @@
       }
     }
 
-    // First make sure --no-implicit-casts disables all downcasts, including
-    // dynamic casts.
-    if (!implicitCasts) {
+    // First make sure that the static analysis options, `implicit-casts: false`
+    // and `strict-casts: true` disable all downcasts, including casts from
+    // `dynamic`.
+    if (!implicitCasts || strictCasts) {
       return false;
     }
 
@@ -1537,9 +1544,11 @@
 
   void updateOptions({
     required bool implicitCasts,
+    required bool strictCasts,
     required bool strictInference,
   }) {
     this.implicitCasts = implicitCasts;
+    this.strictCasts = strictCasts;
     this.strictInference = strictInference;
   }
 
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index a6962f4..05ee001 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -138,7 +138,15 @@
   /// assigned to the [elementType] of the enclosing collection.
   void _verifySpreadForListOrSet(bool isNullAware, Expression expression) {
     var expressionType = expression.typeOrThrow;
-    if (expressionType.isDynamic) return;
+    if (expressionType.isDynamic) {
+      if (typeSystem.strictCasts) {
+        return errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     if (typeSystem.isNonNullableByDefault) {
       if (typeSystem.isSubtypeOf(expressionType, NeverTypeImpl.instance)) {
@@ -224,7 +232,15 @@
   /// its key and values are assignable to [mapKeyType] and [mapValueType].
   void _verifySpreadForMap(bool isNullAware, Expression expression) {
     var expressionType = expression.typeOrThrow;
-    if (expressionType.isDynamic) return;
+    if (expressionType.isDynamic) {
+      if (typeSystem.strictCasts) {
+        return errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_MAP_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     if (typeSystem.isNonNullableByDefault) {
       if (typeSystem.isSubtypeOf(expressionType, NeverTypeImpl.instance)) {
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index c678842..86b03d0 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -285,6 +285,9 @@
   /// re-throwing them)
   bool propagateLinterExceptions = false;
 
+  /// Whether implicit casts should be reported as potential problems.
+  bool strictCasts = false;
+
   /// A flag indicating whether inference failures are allowed, off by default.
   ///
   /// This option is experimental and subject to change.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 85bde05..3dea90e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2259,6 +2259,26 @@
 
     DartType iterableType = node.iterable.typeOrThrow;
 
+    Token? awaitKeyword;
+    var parent = node.parent;
+    if (parent is ForStatement) {
+      awaitKeyword = parent.awaitKeyword;
+    } else if (parent is ForElement) {
+      awaitKeyword = parent.awaitKeyword;
+    }
+
+    // Use an explicit string instead of [loopType] to remove the "<E>".
+    String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable';
+
+    if (iterableType.isDynamic && typeSystem.strictCasts) {
+      errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE,
+        node.iterable,
+        [iterableType, loopNamedType],
+      );
+      return false;
+    }
+
     // TODO(scheglov) use NullableDereferenceVerifier
     if (_isNonNullableByDefault) {
       if (typeSystem.isNullable(iterableType)) {
@@ -2275,14 +2295,6 @@
       return false;
     }
 
-    Token? awaitKeyword;
-    var parent = node.parent;
-    if (parent is ForStatement) {
-      awaitKeyword = parent.awaitKeyword;
-    } else if (parent is ForElement) {
-      awaitKeyword = parent.awaitKeyword;
-    }
-
     // The object being iterated has to implement Iterable<T> for some T that
     // is assignable to the variable's type.
     // TODO(rnystrom): Move this into mostSpecificTypeArgument()?
@@ -2297,8 +2309,6 @@
     }
 
     if (!typeSystem.isAssignableTo(iterableType, requiredSequenceType)) {
-      // Use an explicit string instead of [loopType] to remove the "<E>".
-      String loopNamedType = awaitKeyword != null ? 'Stream' : 'Iterable';
       errorReporter.reportErrorForNode(
         CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE,
         node.iterable,
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 6a393dc..73b4a73 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -139,6 +139,7 @@
   static const String implicitDynamic = 'implicit-dynamic';
 
   // Language options (see AnalysisOptionsImpl for documentation).
+  static const String strictCasts = 'strict-casts';
   static const String strictInference = 'strict-inference';
   static const String strictRawTypes = 'strict-raw-types';
 
@@ -177,7 +178,11 @@
   ];
 
   /// Supported `analyzer` language options.
-  static const List<String> languageOptions = [strictInference, strictRawTypes];
+  static const List<String> languageOptions = [
+    strictCasts,
+    strictInference,
+    strictRawTypes,
+  ];
 
   /// Supported 'analyzer' optional checks options.
   static const List<String> optionalChecksOptions = [
@@ -750,6 +755,9 @@
       AnalysisOptionsImpl options, Object? feature, Object value) {
     var boolValue = toBool(value);
     if (boolValue != null) {
+      if (feature == AnalyzerOptions.strictCasts) {
+        options.strictCasts = boolValue;
+      }
       if (feature == AnalyzerOptions.strictInference) {
         options.strictInference = boolValue;
       }
diff --git a/pkg/analyzer/test/generated/test_analysis_context.dart b/pkg/analyzer/test/generated/test_analysis_context.dart
index 840d225..bdfa64f 100644
--- a/pkg/analyzer/test/generated/test_analysis_context.dart
+++ b/pkg/analyzer/test/generated/test_analysis_context.dart
@@ -43,6 +43,7 @@
     _typeSystemLegacy = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: false,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: _typeProviderLegacy,
     );
@@ -50,6 +51,7 @@
     _typeSystemNonNullableByDefault = TypeSystemImpl(
       implicitCasts: _analysisOptions.implicitCasts,
       isNonNullableByDefault: true,
+      strictCasts: _analysisOptions.strictCasts,
       strictInference: _analysisOptions.strictInference,
       typeProvider: _typeProviderNonNullableByDefault,
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 148433e..1b491ac 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -36,6 +36,7 @@
   final bool implicitCasts;
   final bool implicitDynamic;
   final List<String> lints;
+  final bool strictCasts;
   final bool strictInference;
   final bool strictRawTypes;
   final List<String> unignorableNames;
@@ -45,6 +46,7 @@
     this.implicitCasts = true,
     this.implicitDynamic = true,
     this.lints = const [],
+    this.strictCasts = false,
     this.strictInference = false,
     this.strictRawTypes = false,
     this.unignorableNames = const [],
@@ -59,8 +61,9 @@
       buffer.writeln('    - $experiment');
     }
     buffer.writeln('  language:');
-    buffer.writeln('    strict-raw-types: $strictRawTypes');
+    buffer.writeln('    strict-casts: $strictCasts');
     buffer.writeln('    strict-inference: $strictInference');
+    buffer.writeln('    strict-raw-types: $strictRawTypes');
     buffer.writeln('  strong-mode:');
     buffer.writeln('    implicit-casts: $implicitCasts');
     buffer.writeln('    implicit-dynamic: $implicitDynamic');
@@ -393,13 +396,14 @@
 }
 
 mixin WithNoImplicitCastsMixin on PubPackageResolutionTest {
+  /// Asserts that no errors are reported in [code] when implicit casts are
+  /// allowed, and that [expectedErrors] are reported for the same [code] when
+  /// implicit casts are not allowed.
   Future<void> assertErrorsWithNoImplicitCasts(
     String code,
-    List<ExpectedError> expectedErrorsWhenImplicitCastsDisabled,
+    List<ExpectedError> expectedErrors,
   ) async {
-    newFile(testFilePath, content: code);
-
-    await resolveTestFile();
+    await resolveTestCode(code);
     assertNoErrorsInResult();
 
     disposeAnalysisContextCollection();
@@ -411,8 +415,13 @@
     );
 
     await resolveTestFile();
-    assertErrorsInResult(expectedErrorsWhenImplicitCastsDisabled);
+    assertErrorsInResult(expectedErrors);
   }
+
+  /// Asserts that no errors are reported in [code], both when implicit casts
+  /// are allowed and when implicit casts are not allowed.
+  Future<void> assertNoErrorsWithNoImplicitCasts(String code) async =>
+      assertErrorsWithNoImplicitCasts(code, []);
 }
 
 mixin WithoutConstructorTearoffsMixin on PubPackageResolutionTest {
@@ -427,3 +436,32 @@
   @override
   bool get typeToStringWithNullability => false;
 }
+
+mixin WithStrictCastsMixin on PubPackageResolutionTest {
+  /// Asserts that no errors are reported in [code] when implicit casts are
+  /// allowed, and that [expectedErrors] are reported for the same [code] when
+  /// implicit casts are not allowed.
+  Future<void> assertErrorsWithStrictCasts(
+    String code,
+    List<ExpectedError> expectedErrors,
+  ) async {
+    await resolveTestCode(code);
+    assertNoErrorsInResult();
+
+    disposeAnalysisContextCollection();
+
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(
+        strictCasts: true,
+      ),
+    );
+
+    await resolveTestFile();
+    assertErrorsInResult(expectedErrors);
+  }
+
+  /// Asserts that no errors are reported in [code], both when implicit casts
+  /// are allowed and when implicit casts are not allowed.
+  Future<void> assertNoErrorsWithStrictCasts(String code) async =>
+      assertErrorsWithStrictCasts(code, []);
+}
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index 60ca6a0..226eafa 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -11,8 +11,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ArgumentTypeNotAssignableTest);
-    defineReflectiveTests(ArgumentTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        ArgumentTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(ArgumentTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(ArgumentTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -656,7 +658,7 @@
 }
 
 @reflectiveTest
-class ArgumentTypeNotAssignableWithNoImplicitCastsTest
+class ArgumentTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_functionCall() async {
@@ -708,3 +710,28 @@
     ]);
   }
 }
+
+@reflectiveTest
+class ArgumentTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_functionCall() async {
+    await assertErrorsWithStrictCasts('''
+void f(int i) {}
+void foo(dynamic a) {
+  f(a);
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
+    ]);
+  }
+
+  test_operator() async {
+    await assertErrorsWithStrictCasts('''
+void foo(int i, dynamic a) {
+  i + a;
+}
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 35, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart
index 07abbcd..767bfa9 100644
--- a/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/field_initializer_not_assignable_test.dart
@@ -10,7 +10,9 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(FieldInitializerNotAssignableTest);
-    defineReflectiveTests(FieldInitializerNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        FieldInitializerNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
+    defineReflectiveTests(FieldInitializerNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -53,14 +55,34 @@
 }
 
 @reflectiveTest
-class FieldInitializerNotAssignableWithNoImplicitCastsTest
+class FieldInitializerNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_constructorInitializer() async {
-    await assertErrorsWithNoImplicitCasts(
-      'class A { int i; A(num n) : i = n; }',
+    await assertErrorsWithNoImplicitCasts('''
+class A {
+  int i;
+  A(num n) : i = n;
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 36, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class FieldInitializerNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_constructorInitializer() async {
+    await assertErrorsWithStrictCasts(
+      '''
+class A {
+  int i;
+  A(dynamic a) : i = a;
+}
+''',
       [
-        error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 32, 1),
+        error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 40, 1),
       ],
     );
   }
diff --git a/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
index c75dd89..31ecd85 100644
--- a/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/for_in_of_invalid_type_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(ForInOfInvalidTypeTest);
     defineReflectiveTests(ForInOfInvalidTypeWithoutNullSafetyTest);
+    defineReflectiveTests(ForInOfInvalidTypeWithStrictCastsTest);
   });
 }
 
@@ -183,3 +184,19 @@
 ''');
   }
 }
+
+@reflectiveTest
+class ForInOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_forIn() async {
+    await assertErrorsWithStrictCasts('''
+f(dynamic e) {
+  for (var id in e) {
+    id;
+  }
+}
+''', [
+      error(CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE, 32, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
index a303efd..726f456 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
@@ -11,8 +11,10 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(InvalidAssignment_ImplicitCallReferenceTest);
     defineReflectiveTests(InvalidAssignmentTest);
-    defineReflectiveTests(InvalidAssignmentWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        InvalidAssignmentWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(InvalidAssignmentWithoutNullSafetyTest);
+    defineReflectiveTests(InvalidAssignmentWithStrictCastsTest);
   });
 }
 
@@ -962,24 +964,27 @@
 }
 
 @reflectiveTest
-class InvalidAssignmentWithNoImplicitCastsTest extends PubPackageResolutionTest
+class InvalidAssignmentWithoutNullSafetyAndNoImplicitCastsTest
+    extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_assignment() async {
-    await assertErrorsWithNoImplicitCasts(
-      'void f(num n, int i) { i = n;}',
-      [
-        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 27, 1),
-      ],
-    );
+    await assertErrorsWithNoImplicitCasts('''
+void f(num n, int i) {
+  i = n;
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 29, 1),
+    ]);
   }
 
   test_compoundAssignment() async {
-    await assertErrorsWithNoImplicitCasts(
-      'void f(num n, int i) { i += n; }',
-      [
-        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 28, 1),
-      ],
-    );
+    await assertErrorsWithNoImplicitCasts('''
+void f(num n, int i) {
+  i += n;
+}
+''', [
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 30, 1),
+    ]);
   }
 
   @failingTest
@@ -1008,11 +1013,11 @@
 
   test_numericOps() async {
     // Regression test for https://github.com/dart-lang/sdk/issues/26912
-    await assertErrorsWithNoImplicitCasts(r'''
+    await assertNoErrorsWithNoImplicitCasts('''
 void f(int x, int y) {
   x += y;
 }
-''', []);
+''');
   }
 
   @failingTest
@@ -1088,3 +1093,16 @@
     ]);
   }
 }
+
+@reflectiveTest
+class InvalidAssignmentWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_assignment() async {
+    await assertErrorsWithStrictCasts('''
+dynamic a;
+int b = a;
+''', [
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 19, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
index 8d45f28..6a85dc3 100644
--- a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ListElementTypeNotAssignableTest);
-    defineReflectiveTests(ListElementTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        ListElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(ListElementTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(ListElementTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -233,7 +235,7 @@
 }
 
 @reflectiveTest
-class ListElementTypeNotAssignableWithNoImplicitCastsTest
+class ListElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_dynamic() async {
@@ -291,3 +293,37 @@
 class ListElementTypeNotAssignableWithoutNullSafetyTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, ListElementTypeNotAssignableTestCases {}
+
+@reflectiveTest
+class ListElementTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>[if (c) 0 else a];
+}
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>[if (c) a];
+}
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Iterable<dynamic> a) {
+  <int>[...a];
+}
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 41, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
index 1216de7..ca3c915 100644
--- a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MapKeyTypeNotAssignableTest);
-    defineReflectiveTests(MapKeyTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        MapKeyTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(MapKeyTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(MapKeyTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -238,7 +240,7 @@
 }
 
 @reflectiveTest
-class MapKeyTypeNotAssignableWithNoImplicitCastsTest
+class MapKeyTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_key_dynamic() async {
@@ -302,3 +304,37 @@
 ''');
   }
 }
+
+@reflectiveTest
+class MapKeyTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) 0: 0 else a: 0};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 58, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) a: 0 };
+}
+''', [
+      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 48, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Map<dynamic, int> a) {
+  <int, int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 46, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
index 212b70b..4cebc25 100644
--- a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MapValueTypeNotAssignableTest);
-    defineReflectiveTests(MapValueTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        MapValueTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(MapValueTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(MapValueTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -232,7 +234,7 @@
 }
 
 @reflectiveTest
-class MapValueTypeNotAssignableWithNoImplicitCastsTest
+class MapValueTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_value_dynamic() async {
@@ -296,3 +298,37 @@
 ''');
   }
 }
+
+@reflectiveTest
+class MapValueTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) 0: 0 else 0: a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 61, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int, int>{if (c) 0: a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 51, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Map<int, dynamic> a) {
+  <int, int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 46, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
index d96e7f3..3f99747 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_condition_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolConditionTest);
-    defineReflectiveTests(NonBoolConditionWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(NonBoolConditionWithNullSafetyTest);
+    defineReflectiveTests(NonBoolConditionWithStrictCastsTest);
   });
 }
 
@@ -214,7 +216,31 @@
 }
 
 @reflectiveTest
-class NonBoolConditionWithNoImplicitCastsTest extends PubPackageResolutionTest
+class NonBoolConditionWithNullSafetyTest extends PubPackageResolutionTest {
+  test_if_null() async {
+    await assertErrorsInCode(r'''
+void f(Null a) {
+  if (a) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 23, 1),
+    ]);
+  }
+
+  test_ternary_condition_null() async {
+    await assertErrorsInCode(r'''
+void f(Null a) {
+  a ? 0 : 1;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 19, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class NonBoolConditionWithoutNullSafetyAndNoImplicitCastsTest
+    extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_map_ifElement_condition_dynamic() async {
     await assertErrorsWithNoImplicitCasts(r'''
@@ -258,26 +284,25 @@
 }
 
 @reflectiveTest
-class NonBoolConditionWithNullSafetyTest extends PubPackageResolutionTest {
-  test_if_null() async {
-    await assertErrorsInCode(r'''
-m() {
-  Null x;
-  if (x) {}
+class NonBoolConditionWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_map_ifElement_condition() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic c) {
+  <int, int>{if (c) 0: 0};
 }
 ''', [
-      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 22, 1),
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 37, 1),
     ]);
   }
 
-  test_ternary_condition_null() async {
-    await assertErrorsInCode(r'''
-m() {
-  Null x;
-  x ? 0 : 1;
+  test_set_ifElement_condition() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic c) {
+  <int>{if (c) 0};
 }
 ''', [
-      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 18, 1),
+      error(CompileTimeErrorCode.NON_BOOL_CONDITION, 32, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart
index 0a12cfb..1305b0d 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_expression_test.dart
@@ -10,6 +10,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolExpressionTest);
+    defineReflectiveTests(NonBoolExpressionWithStrictCastsTest);
   });
 }
 
@@ -47,3 +48,17 @@
     ]);
   }
 }
+
+@reflectiveTest
+class NonBoolExpressionWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_assert() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  assert(a);
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_EXPRESSION, 29, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
index 6fb1e92..f0578ad 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_negation_expression_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolNegationExpressionTest);
     defineReflectiveTests(NonBoolNegationExpressionWithNullSafetyTest);
+    defineReflectiveTests(NonBoolNegationExpressionWithStrictCastsTest);
   });
 }
 
@@ -50,14 +51,26 @@
 class NonBoolNegationExpressionWithNullSafetyTest
     extends PubPackageResolutionTest {
   test_null() async {
-    await assertErrorsInCode(r'''
-m() {
-  Null x;
+    await assertErrorsInCode('''
+void m(Null x) {
   !x;
 }
 ''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
-      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 19, 1),
+      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 20, 1),
+    ]);
+  }
+}
+
+@reflectiveTest
+class NonBoolNegationExpressionWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_negation() async {
+    await assertErrorsWithStrictCasts(r'''
+void f(dynamic a) {
+  !a;
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_NEGATION_EXPRESSION, 23, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
index ea06d2a..1b25120 100644
--- a/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_bool_operand_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NonBoolOperandTest);
     defineReflectiveTests(NonBoolOperandWithNullSafetyTest);
+    defineReflectiveTests(NonBoolOperandWithStrictCastsTest);
   });
 }
 
@@ -110,3 +111,17 @@
     ]);
   }
 }
+
+@reflectiveTest
+class NonBoolOperandWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_and() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  if(a && true) {}
+}
+''', [
+      error(CompileTimeErrorCode.NON_BOOL_OPERAND, 25, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
index d81a21a..d968410 100644
--- a/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_iterable_spread_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NotIterableSpreadTest);
     defineReflectiveTests(NotIterableSpreadWithoutNullSafetyTest);
+    defineReflectiveTests(NotIterableSpreadWithStrictCastsTest);
   });
 }
 
@@ -112,3 +113,27 @@
 @reflectiveTest
 class NotIterableSpreadWithoutNullSafetyTest extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, NotIterableSpreadTestCases {}
+
+@reflectiveTest
+class NotIterableSpreadWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_list() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  [...a];
+}
+''', [
+      error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 26, 1),
+    ]);
+  }
+
+  test_set() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  <int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 31, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
index 3c008f9..aa8cf06 100644
--- a/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_map_spread_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(NotMapSpreadTest);
     defineReflectiveTests(NotMapSpreadWithoutNullSafetyTest);
+    defineReflectiveTests(NotMapSpreadWithStrictCastsTest);
   });
 }
 
@@ -102,3 +103,17 @@
 @reflectiveTest
 class NotMapSpreadWithoutNullSafetyTest extends PubPackageResolutionTest
     with NotMapSpreadTestCases, WithoutNullSafetyMixin {}
+
+@reflectiveTest
+class NotMapSpreadWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_map() async {
+    await assertErrorsWithStrictCasts('''
+void f(dynamic a) {
+  <int, String>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.NOT_MAP_SPREAD, 39, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
index ef2237d..1a11708 100644
--- a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ReturnOfInvalidTypeTest);
-    defineReflectiveTests(ReturnOfInvalidTypeWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        ReturnOfInvalidTypeWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(ReturnOfInvalidTypeWithoutNullSafetyTest);
+    defineReflectiveTests(ReturnOfInvalidTypeWithStrictCastsTest);
   });
 }
 
@@ -547,7 +549,7 @@
 }
 
 @reflectiveTest
-class ReturnOfInvalidTypeWithNoImplicitCastsTest
+class ReturnOfInvalidTypeWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_return() async {
@@ -571,3 +573,25 @@
 @reflectiveTest
 class ReturnOfInvalidTypeWithoutNullSafetyTest extends PubPackageResolutionTest
     with ReturnOfInvalidTypeTestCases, WithoutNullSafetyMixin {}
+
+@reflectiveTest
+class ReturnOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_return() async {
+    await assertErrorsWithStrictCasts('''
+int f(dynamic a) => a;
+''', [
+      error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 20, 1),
+    ]);
+  }
+
+  test_return_async() async {
+    await assertErrorsWithStrictCasts('''
+Future<int> f(dynamic a) async {
+  return a;
+}
+''', [
+      error(CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION, 42, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
index a74f2cc..d5cb62b 100644
--- a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
@@ -10,8 +10,10 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(SetElementTypeNotAssignableTest);
-    defineReflectiveTests(SetElementTypeNotAssignableWithNoImplicitCastsTest);
+    defineReflectiveTests(
+        SetElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest);
     defineReflectiveTests(SetElementTypeNotAssignableWithoutNullSafetyTest);
+    defineReflectiveTests(SetElementTypeNotAssignableWithStrictCastsTest);
   });
 }
 
@@ -198,7 +200,7 @@
 }
 
 @reflectiveTest
-class SetElementTypeNotAssignableWithNoImplicitCastsTest
+class SetElementTypeNotAssignableWithoutNullSafetyAndNoImplicitCastsTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, WithNoImplicitCastsMixin {
   test_ifElement_falseBranch_dynamic() async {
@@ -256,3 +258,37 @@
 class SetElementTypeNotAssignableWithoutNullSafetyTest
     extends PubPackageResolutionTest
     with WithoutNullSafetyMixin, SetElementTypeNotAssignableTestCases {}
+
+@reflectiveTest
+class SetElementTypeNotAssignableWithStrictCastsTest
+    extends PubPackageResolutionTest with WithStrictCastsMixin {
+  test_ifElement_falseBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>{if (c) 0 else a};
+}
+''', [
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
+    ]);
+  }
+
+  test_ifElement_trueBranch() async {
+    await assertErrorsWithStrictCasts('''
+void f(bool c, dynamic a) {
+  <int>{if (c) a};
+}
+''', [
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
+    ]);
+  }
+
+  test_spread() async {
+    await assertErrorsWithStrictCasts('''
+void f(Iterable<dynamic> a) {
+  <int>{...a};
+}
+''', [
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 41, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
index 6eda8bd..e064365 100644
--- a/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/yield_of_invalid_type_test.dart
@@ -11,6 +11,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(YieldOfInvalidTypeTest);
     defineReflectiveTests(YieldOfInvalidTypeWithoutNullSafetyTest);
+    defineReflectiveTests(YieldOfInvalidTypeWithStrictCastsTest);
   });
 }
 
@@ -448,3 +449,27 @@
 @reflectiveTest
 class YieldOfInvalidTypeWithoutNullSafetyTest extends PubPackageResolutionTest
     with YieldOfInvalidTypeTestCases, WithoutNullSafetyMixin {}
+
+@reflectiveTest
+class YieldOfInvalidTypeWithStrictCastsTest extends PubPackageResolutionTest
+    with WithStrictCastsMixin {
+  test_yieldEach_asyncStar() async {
+    await assertErrorsWithStrictCasts('''
+f(dynamic a) async* {
+  yield* a;
+}
+''', [
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 31, 1),
+    ]);
+  }
+
+  test_yieldEach_syncStar() async {
+    await assertErrorsWithStrictCasts('''
+f(dynamic a) sync* {
+  yield* a;
+}
+''', [
+      error(CompileTimeErrorCode.YIELD_EACH_OF_INVALID_TYPE, 30, 1),
+    ]);
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 5e57c8b..afb6393 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -292,6 +292,7 @@
     return TypeSystemImpl(
         implicitCasts: typeSystem.implicitCasts,
         isNonNullableByDefault: true,
+        strictCasts: typeSystem.strictCasts,
         strictInference: typeSystem.strictInference,
         typeProvider: nnbdTypeProvider);
   }
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index fcec048..2be4a72 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -70,6 +70,7 @@
         TypeSystemImpl(
           implicitCasts: true,
           isNonNullableByDefault: false,
+          strictCasts: false,
           strictInference: false,
           typeProvider: typeProvider,
         ),
@@ -500,6 +501,7 @@
     var typeSystem = TypeSystemImpl(
       isNonNullableByDefault: false,
       implicitCasts: true,
+      strictCasts: false,
       strictInference: false,
       typeProvider: typeProvider,
     );
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index 5aa9504..2d4f42c 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -37,40 +37,13 @@
   /// values, the iteration order is unspecified except that it will stay the
   /// same as long as the map isn't changed.
   ///
-  /// If [equals] is provided, it is used to compare the keys in the table with
+  /// If [equals] is provided, it is used to compare the keys in the map with
   /// new keys. If [equals] is omitted, the key's own [Object.==] is used
   /// instead.
   ///
   /// Similar, if [hashCode] is provided, it is used to produce a hash value
-  /// for keys in order to place them in the hash table. If it is omitted, the
-  /// key's own [Object.hashCode] is used.
-  ///
-  /// If using methods like [operator []], [remove] and [containsKey] together
-  /// with a custom equality and hashcode, an extra `isValidKey` function
-  /// can be supplied. This function is called before calling [equals] or
-  /// [hashCode] with an argument that may not be a [K] instance, and if the
-  /// call returns false, the key is assumed to not be in the set.
-  /// The [isValidKey] function defaults to just testing if the object is a
-  /// [K] instance.
-  ///
-  /// Example:
-  /// ```dart template:expression
-  /// HashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
-  ///                  hashCode: (int e) => e % 5)
-  /// ```
-  /// This example map does not need an `isValidKey` function to be passed.
-  /// The default function accepts only `int` values, which can safely be
-  /// passed to both the `equals` and `hashCode` functions.
-  ///
-  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
-  /// the default `isValidKey` instead accepts all keys.
-  /// The default equality and hashcode operations are assumed to work on all
-  /// objects.
-  ///
-  /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode]
-  /// and `isValidKey` is omitted, the resulting map is identity based,
-  /// and the `isValidKey` defaults to accepting all keys.
-  /// Such a map can be created directly using [HashMap.identity].
+  /// for keys in order to place them in the map. If [hashCode] is omitted,
+  /// the key's own [Object.hashCode] is used.
   ///
   /// The used `equals` and `hashCode` method should always be consistent,
   /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash
@@ -79,7 +52,36 @@
   /// unpredictable.
   ///
   /// If you supply one of [equals] and [hashCode],
-  /// you should generally also to supply the other.
+  /// you should generally also supply the other.
+  ///
+  /// Some [equals] or [hashCode] functions might not work for all objects.
+  /// If [isValidKey] is supplied, it's used to check a potential key
+  /// which is not necessarily an instance of [K], like the arguments to
+  /// [operator []], [remove] and [containsKey], which are typed as `Object?`.
+  /// If [isValidKey] returns `false`, for an object, the [equals] and
+  /// [hashCode] functions are not called, and no key equal to that object
+  /// is assumed to be in the map.
+  /// The [isValidKey] function defaults to just testing if the object is an
+  /// instance of [K].
+  ///
+  /// Example:
+  /// ```dart template:expression
+  /// HashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
+  ///                  hashCode: (int e) => e % 5)
+  /// ```
+  /// This example map does not need an `isValidKey` function to be passed.
+  /// The default function accepts precisely `int` values, which can safely be
+  /// passed to both the `equals` and `hashCode` functions.
+  ///
+  /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
+  /// the default `isValidKey` instead accepts all keys.
+  /// The default equality and hashcode operations are known to work on all
+  /// objects.
+  ///
+  /// Likewise, if `equals` is [identical], `hashCode` is [identityHashCode]
+  /// and `isValidKey` is omitted, the resulting map is identity based,
+  /// and the `isValidKey` defaults to accepting all keys.
+  /// Such a map can be created directly using [HashMap.identity].
   external factory HashMap(
       {bool Function(K, K)? equals,
       int Function(K)? hashCode,
@@ -87,6 +89,9 @@
 
   /// Creates an unordered identity-based map.
   ///
+  /// Keys of this map are considered equal only to the same object,
+  /// and does not use [Object.==] at all.
+  ///
   /// Effectively a shorthand for:
   /// ```dart
   /// HashMap<K, V>(equals: identical, hashCode: identityHashCode)
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index ee8fed0..1f94ffb 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -25,12 +25,7 @@
   /// Create a hash set using the provided [equals] as equality.
   ///
   /// The provided [equals] must define a stable equivalence relation, and
-  /// [hashCode] must be consistent with [equals]. If the [equals] or [hashCode]
-  /// methods won't work on all objects, but only on some instances of E, the
-  /// [isValidKey] predicate can be used to restrict the keys that the functions
-  /// are applied to.
-  /// Any key for which [isValidKey] returns false is automatically assumed
-  /// to not be in the set when asking `contains`.
+  /// [hashCode] must be consistent with [equals].
   ///
   /// If [equals] or [hashCode] are omitted, the set uses
   /// the elements' intrinsic [Object.==] and [Object.hashCode].
@@ -38,18 +33,20 @@
   /// If you supply one of [equals] and [hashCode],
   /// you should generally also to supply the other.
   ///
-  /// If the supplied `equals` or `hashCode` functions won't work on all [E]
-  /// objects, and the map will be used in a setting where a non-`E` object
-  /// is passed to, e.g., `contains`, then the [isValidKey] function should
-  /// also be supplied.
-  ///
-  /// If [isValidKey] is omitted, it defaults to testing if the object is an
-  /// [E] instance. That means that:
+  /// Some [equals] or [hashCode] functions might not work for all objects.
+  /// If [isValidKey] is supplied, it's used to check a potential element
+  /// which is not necessarily an instance of [E], like the argument to
+  /// [contains] which is typed as `Object?`.
+  /// If [isValidKey] returns `false`, for an object, the [equals] and
+  /// [hashCode] functions are not called, and no key equal to that object
+  /// is assumed to be in the map.
+  /// The [isValidKey] function defaults to just testing if the object is an
+  /// instance of [E], which means that:
   /// ```dart template:expression
   /// HashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
   ///              hashCode: (int e) => e % 5)
   /// ```
-  /// does not need an `isValidKey` argument, because it defaults to only
+  /// does not need an `isValidKey` argument because it defaults to only
   /// accepting `int` values which are accepted by both `equals` and `hashCode`.
   ///
   /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index cfab8f3..646b581 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -8,7 +8,7 @@
 ///
 /// The insertion order of keys is remembered,
 /// and keys are iterated in the order they were inserted into the map.
-/// Values are iterated in their corresponding key's order.
+/// Values and entries are iterated in their corresponding key's order.
 /// Changing a key's value, when the key is already in the map,
 /// does not change the iteration order,
 /// but removing the key and adding it again
@@ -30,21 +30,31 @@
   /// for keys in order to place them in the hash table. If it is omitted, the
   /// key's own [Object.hashCode] is used.
   ///
-  /// If using methods like [operator []], [remove] and [containsKey] together
-  /// with a custom equality and hashcode, an extra `isValidKey` function
-  /// can be supplied. This function is called before calling [equals] or
-  /// [hashCode] with an argument that may not be a [K] instance, and if the
-  /// call returns false, the key is assumed to not be in the set.
-  /// The [isValidKey] function defaults to just testing if the object is a
-  /// [K] instance.
+  /// The used `equals` and `hashCode` method should always be consistent,
+  /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash
+  /// of an object, or what it compares equal to, should not change while the
+  /// object is in the table. If it does change, the result is unpredictable.
+  ///
+  /// If you supply one of [equals] and [hashCode],
+  /// you should generally also supply the other.
+  ///
+  /// Some [equals] or [hashCode] functions might not work for all objects.
+  /// If [isValidKey] is supplied, it's used to check a potential key
+  /// which is not necessarily an instance of [K], like the arguments to
+  /// [operator []], [remove] and [containsKey], which are typed as `Object?`.
+  /// If [isValidKey] returns `false`, for an object, the [equals] and
+  /// [hashCode] functions are not called, and no key equal to that object
+  /// is assumed to be in the map.
+  /// The [isValidKey] function defaults to just testing if the object is an
+  /// instance of [K].
   ///
   /// Example:
   /// ```dart template:expression
-  /// LinkedHashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
-  ///                        hashCode: (int e) => e % 5)
+  /// LikedHashMap<int,int>(equals: (int a, int b) => (b - a) % 5 == 0,
+  ///                       hashCode: (int e) => e % 5)
   /// ```
   /// This example map does not need an `isValidKey` function to be passed.
-  /// The default function accepts only `int` values, which can safely be
+  /// The default function accepts precisely `int` values, which can safely be
   /// passed to both the `equals` and `hashCode` functions.
   ///
   /// If neither `equals`, `hashCode`, nor `isValidKey` is provided,
@@ -56,14 +66,6 @@
   /// and `isValidKey` is omitted, the resulting map is identity based,
   /// and the `isValidKey` defaults to accepting all keys.
   /// Such a map can be created directly using [LinkedHashMap.identity].
-  ///
-  /// The used `equals` and `hashCode` method should always be consistent,
-  /// so that if `equals(a, b)` then `hashCode(a) == hashCode(b)`. The hash
-  /// of an object, or what it compares equal to, should not change while the
-  /// object is in the table. If it does change, the result is unpredictable.
-  ///
-  /// If you supply one of [equals] and [hashCode],
-  /// you should generally also to supply the other.
   external factory LinkedHashMap(
       {bool Function(K, K)? equals,
       int Function(K)? hashCode,
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index 43d9a52..66be66c 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -30,28 +30,20 @@
   /// [equals] and [hashCode].
   ///
   /// The provided [equals] must define a stable equivalence relation, and
-  /// [hashCode] must be consistent with [equals]. If the [equals] or [hashCode]
-  /// methods won't work on all objects, but only on some instances of E, the
-  /// [isValidKey] predicate can be used to restrict the keys that the functions
-  /// are applied to.
-  /// Any key for which [isValidKey] returns false is automatically assumed
-  /// to not be in the set when asking `contains`.
-  ///
-  /// If [equals] or [hashCode] are omitted, the set uses
-  /// the elements' intrinsic [Object.==] and [Object.hashCode],
-  /// and [isValidKey] is ignored since these operations are assumed
-  /// to work on all objects.
+  /// [hashCode] must be consistent with [equals].
   ///
   /// If you supply one of [equals] and [hashCode],
   /// you should generally also to supply the other.
   ///
-  /// If the supplied `equals` or `hashCode` functions won't work on all [E]
-  /// objects, and the map will be used in a setting where a non-`E` object
-  /// is passed to, e.g., `contains`, then the [isValidKey] function should
-  /// also be supplied.
-  ///
-  /// If [isValidKey] is omitted, it defaults to testing if the object is an
-  /// [E] instance. That means that:
+  /// Some [equals] or [hashCode] functions might not work for all objects.
+  /// If [isValidKey] is supplied, it's used to check a potential element
+  /// which is not necessarily an instance of [E], like the argument to
+  /// [contains] which is typed as `Object?`.
+  /// If [isValidKey] returns `false`, for an object, the [equals] and
+  /// [hashCode] functions are not called, and no key equal to that object
+  /// is assumed to be in the map.
+  /// The [isValidKey] function defaults to just testing if the object is an
+  /// instance of [E], which means that:
   /// ```dart template:expression
   /// LinkedHashSet<int>(equals: (int e1, int e2) => (e1 - e2) % 5 == 0,
   ///                    hashCode: (int e) => e % 5)
diff --git a/tools/VERSION b/tools/VERSION
index 3fdef2c..b0b82aa 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 1
+PRERELEASE 2
 PRERELEASE_PATCH 0
\ No newline at end of file