Version 2.10.0-3.0.dev

Merge commit '0a19e8dbfe53d2a9a8fd6850172dce89f96a42e9' into dev
diff --git a/BUILD.gn b/BUILD.gn
index fe0376d..2f73ff3 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -165,20 +165,27 @@
     resource_files = [
       ".packages",
       "pkg/testing/test/hello_test.dart",
+      "tools/addlatexhash.dart",
     ]
     resource_dirs = [
-      "tests/standalone",
-      "tests/language_2",
+      "tests/standalone_2",
       "pkg/async_helper",
       "pkg/expect",
       "pkg/meta",
+      "pkg/native_stack_traces",
       "pkg/smith",
       "third_party/pkg/args",
       "third_party/pkg/async",
+      "third_party/pkg/charcode",
       "third_party/pkg/collection",
+      "third_party/pkg/convert",
+      "third_party/pkg/crypto",
+      "third_party/pkg/http",
+      "third_party/pkg/http_parser",
       "third_party/pkg/path",
       "third_party/pkg/pool",
       "third_party/pkg/stack_trace",
+      "third_party/pkg/typed_data",
     ]
 
     resources = []
diff --git a/DEPS b/DEPS
index c9fc55e..9c5288e 100644
--- a/DEPS
+++ b/DEPS
@@ -44,11 +44,11 @@
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
   # has.
-  "co19_rev": "86c948fbe7c8a9e74f572038f2ec70dfce7f20b0",
+  "co19_rev": "e3d6ccfe8fa278041316f7dc958fdd8c2b447b6c",
   "co19_2_rev": "e48b3090826cf40b8037648f19d211e8eab1b4b6",
 
   # The internal benchmarks to use. See go/dart-benchmarks-internal
-  "benchmarks_internal_rev": "9bc9e373b3d3cacdd7aba906caea77075c6cd2e3",
+  "benchmarks_internal_rev": "1682e8c568cf1899a6da6b5993f0506949253b22",
   "checkout_benchmarks_internal": False,
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
diff --git a/build/fuchsia/dart.cmx b/build/fuchsia/dart.cmx
index b4546c1..f8f5750 100644
--- a/build/fuchsia/dart.cmx
+++ b/build/fuchsia/dart.cmx
@@ -8,7 +8,8 @@
       "deprecated-ambient-replace-as-executable",
       "root-ssl-certificates",
       "isolated-cache-storage",
-      "isolated-persistent-storage"
+      "isolated-persistent-storage",
+      "isolated-temp"
     ],
     "services": [
       "fuchsia.deprecatedtimezone.Timezone",
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 2dd17b7..82c40dc 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -576,9 +576,6 @@
 
   /// Retrieves the type that the [variable] is promoted to, if the [variable]
   /// is currently promoted.  Otherwise returns `null`.
-  ///
-  /// For testing only.  Please use [variableRead] instead.
-  @visibleForTesting
   Type promotedType(Variable variable);
 
   /// Call this method just before visiting one of the cases in the body of a
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 61e97af..531cf04 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -5410,6 +5410,17 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeJsInteropAnonymousFactoryPositionalParameters =
+    messageJsInteropAnonymousFactoryPositionalParameters;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageJsInteropAnonymousFactoryPositionalParameters =
+    const MessageCode("JsInteropAnonymousFactoryPositionalParameters",
+        message:
+            r"""Factory constructors for @anonymous JS interop classes should not contain any positional parameters.""",
+        tip: r"""Try replacing them with named parameters instead.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeJsInteropIndexNotSupported =
     messageJsInteropIndexNotSupported;
 
diff --git a/pkg/_js_interop_checks/lib/js_interop_checks.dart b/pkg/_js_interop_checks/lib/js_interop_checks.dart
index 7005741..08cbb83 100644
--- a/pkg/_js_interop_checks/lib/js_interop_checks.dart
+++ b/pkg/_js_interop_checks/lib/js_interop_checks.dart
@@ -8,6 +8,7 @@
     show
         Message,
         LocatedMessage,
+        messageJsInteropAnonymousFactoryPositionalParameters,
         messageJsInteropIndexNotSupported,
         messageJsInteropNamedParameters,
         messageJsInteropNonExternalConstructor;
@@ -32,7 +33,20 @@
           procedure.location.file);
     }
 
-    if (!isAnonymousClassMember(procedure) || !procedure.isFactory) {
+    var isAnonymousFactory =
+        isAnonymousClassMember(procedure) && procedure.isFactory;
+
+    if (isAnonymousFactory) {
+      if (procedure.function != null &&
+          !procedure.function.positionalParameters.isEmpty) {
+        var firstPositionalParam = procedure.function.positionalParameters[0];
+        _diagnosticsReporter.report(
+            messageJsInteropAnonymousFactoryPositionalParameters,
+            firstPositionalParam.fileOffset,
+            firstPositionalParam.name.length,
+            firstPositionalParam.location.file);
+      }
+    } else {
       // Only factory constructors for anonymous classes are allowed to have
       // named parameters.
       _checkNoNamedParameters(procedure.function);
@@ -57,12 +71,12 @@
   /// Reports an error if [functionNode] has named parameters.
   void _checkNoNamedParameters(FunctionNode functionNode) {
     if (functionNode != null && !functionNode.namedParameters.isEmpty) {
-      var firstNameParam = functionNode.namedParameters[0];
+      var firstNamedParam = functionNode.namedParameters[0];
       _diagnosticsReporter.report(
           messageJsInteropNamedParameters,
-          firstNameParam.fileOffset,
-          firstNameParam.name.length,
-          firstNameParam.location.file);
+          firstNamedParam.fileOffset,
+          firstNamedParam.name.length,
+          firstNamedParam.location.file);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index e2e4478..1e64f55 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -408,11 +408,11 @@
     while (entity is AstNode) {
       if (entity is SimpleIdentifier) {
         var identifier = entity.name;
-        if (offset >= entity.offset &&
-            offset - entity.offset < identifier.length) {
+        if (offset >= entity.offset && offset < entity.end) {
           return identifier.substring(0, offset - entity.offset);
+        } else if (offset == entity.end) {
+          return identifier;
         }
-        return identifier;
       }
       var children = (entity as AstNode).childEntities;
       entity = children.isEmpty ? null : children.first;
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index ec4e330..1ecf7f5 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -11,14 +11,24 @@
 import 'package:analysis_server/src/services/correction/dart/add_override.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_documentation_into_line.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_contains.dart';
+import 'package:analysis_server/src/services/correction/dart/create_method.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_argument.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_await.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_const.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_duplicate_case.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_catch.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_constructor_body.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_empty_else.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_empty_statement.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_initializer.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_operator.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_type_annotation.dart';
 import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_new.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_cascade_with_dot.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_colon_with_equals.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_null_with_closure.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_var.dart';
+import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analysis_server/src/services/linter/lint_names.dart';
@@ -43,6 +53,17 @@
         ReplaceCascadeWithDot.newInstance,
     LintNames.avoid_types_on_closure_parameters:
         RemoveTypeAnnotation.newInstance,
+    LintNames.await_only_futures: RemoveAwait.newInstance,
+    LintNames.curly_braces_in_flow_control_structures:
+        UseCurlyBraces.newInstance,
+    LintNames.empty_catches: RemoveEmptyCatch.newInstance,
+    LintNames.empty_constructor_bodies: RemoveEmptyConstructorBody.newInstance,
+    LintNames.empty_statements: RemoveEmptyStatement.newInstance,
+    LintNames.hash_and_equals: CreateMethod.equalsOrHashCode,
+    LintNames.no_duplicate_case_values: RemoveDuplicateCase.newInstance,
+    LintNames.null_closures: ReplaceNullWithClosure.newInstance,
+    LintNames.omit_local_variable_types: ReplaceWithVar.newInstance,
+    LintNames.prefer_adjacent_string_concatenation: RemoveOperator.newInstance,
     LintNames.prefer_contains: ConvertToContains.newInstance,
     LintNames.prefer_equal_for_default_values:
         ReplaceColonWithEquals.newInstance,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
index 48ae964..2af769a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_explicit_cast.dart
@@ -25,6 +25,11 @@
     }
 
     var fromType = target.staticType;
+    if (fromType == typeProvider.nullType) {
+      // There would only be a diagnostic if the `toType` is not nullable, in
+      // which case a cast won't fix the problem.
+      return;
+    }
     DartType toType;
     var parent = target.parent;
     if (parent is CascadeExpression && target == parent.target) {
@@ -39,6 +44,12 @@
       // TODO(brianwilkerson) Handle function arguments.
       return;
     }
+    if (typeSystem.isAssignableTo(
+        toType, typeSystem.promoteToNonNull(fromType))) {
+      // The only reason that `fromType` can't be assigned to `toType` is
+      // because it's nullable, in which case a cast won't fix the problem.
+      return;
+    }
     // TODO(brianwilkerson) Handle `toSet` in a manner similar to the below.
     if (target.isToListMethodInvocation) {
       var targetTarget = (target as MethodInvocation).target;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
new file mode 100644
index 0000000..c66d036
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_null_check.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/precedence.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddNullCheck extends CorrectionProducer {
+  @override
+  FixKind get fixKind => DartFixKind.ADD_NULL_CHECK;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    if (!unit.featureSet.isEnabled(Feature.non_nullable)) {
+      // Don't suggest a feature that isn't supported.
+      return;
+    }
+    Expression target;
+    if (coveredNode is Expression) {
+      target = coveredNode;
+    } else {
+      return;
+    }
+
+    var fromType = target.staticType;
+    if (fromType == typeProvider.nullType) {
+      // Adding a null check after an explicit `null` is pointless.
+      return;
+    }
+    DartType toType;
+    var parent = target.parent;
+    if (parent is AssignmentExpression && target == parent.rightHandSide) {
+      toType = parent.leftHandSide.staticType;
+    } else if (parent is VariableDeclaration && target == parent.initializer) {
+      toType = parent.declaredElement.type;
+    } else if (parent is ArgumentList) {
+      toType = target.staticParameterElement.type;
+    } else {
+      return;
+    }
+    if (!typeSystem.isAssignableTo(
+        toType, typeSystem.promoteToNonNull(fromType))) {
+      // The reason that `fromType` can't be assigned to `toType` is more than
+      // just because it's nullable, in which case a null check won't fix the
+      // problem.
+      return;
+    }
+    var needsParentheses = target.precedence < Precedence.postfix;
+    await builder.addDartFileEdit(file, (builder) {
+      if (needsParentheses) {
+        builder.addSimpleInsertion(target.offset, '(');
+      }
+      builder.addInsertion(target.end, (builder) {
+        if (needsParentheses) {
+          builder.write(')');
+        }
+        builder.write('!');
+      });
+    });
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static AddNullCheck newInstance() => AddNullCheck();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
index 049461d..3ef7bda 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_duplicate_case.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -15,9 +16,19 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (coveredNode is SwitchCase) {
+    var node = coveredNode;
+    if (node is SwitchCase) {
+      var parent = node.parent as SwitchStatement;
+      var members = parent.members;
+      var index = members.indexOf(node);
       await builder.addDartFileEdit(file, (builder) {
-        builder.addDeletion(utils.getLinesRange(range.node(coveredNode)));
+        SourceRange deletionRange;
+        if (index > 0 && members[index - 1].statements.isNotEmpty) {
+          deletionRange = range.node(node);
+        } else {
+          deletionRange = range.startEnd(node, node.colon);
+        }
+        builder.addDeletion(utils.getLinesRange(deletionRange));
       });
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
index d37ce1e..8e9ede9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_cascade_with_dot.dart
@@ -11,6 +11,16 @@
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 class ReplaceCascadeWithDot extends CorrectionProducer {
+  static final Map<TokenType, String> _indexReplacement = {
+    TokenType.PERIOD_PERIOD: '',
+    TokenType.QUESTION_PERIOD_PERIOD: '?',
+  };
+
+  static final Map<TokenType, String> _propertyReplacement = {
+    TokenType.PERIOD_PERIOD: '.',
+    TokenType.QUESTION_PERIOD_PERIOD: '?.',
+  };
+
   @override
   FixKind get fixKind => DartFixKind.REPLACE_CASCADE_WITH_DOT;
 
@@ -20,52 +30,41 @@
     if (node is CascadeExpression) {
       var sections = node.cascadeSections;
       if (sections.length == 1) {
-        var section = sections[0];
-        Token cascadeOperator;
-        if (section is MethodInvocation) {
-          cascadeOperator = section.operator;
-        } else if (section is PropertyAccess) {
-          cascadeOperator = section.operator;
-        } else if (section is IndexExpression) {
-          await _handleIndexExpression(builder, section);
-          return;
-        } else if (section is AssignmentExpression) {
-          var leftHandSide = section.leftHandSide;
-          if (leftHandSide is PropertyAccess) {
-            cascadeOperator = leftHandSide.operator;
-          } else if (leftHandSide is IndexExpression) {
-            await _handleIndexExpression(builder, leftHandSide);
-            return;
-          } else {
-            return;
-          }
-        } else {
-          return;
-        }
-        var type = cascadeOperator.type;
-        if (type == TokenType.PERIOD_PERIOD ||
-            type == TokenType.QUESTION_PERIOD_PERIOD) {
-          await builder.addDartFileEdit(file, (builder) {
-            var end = cascadeOperator.end;
-            builder.addDeletion(range.startOffsetEndOffset(end - 1, end));
-          });
-        }
+        await _replaceFor(builder, sections[0]);
       }
     }
   }
 
-  void _handleIndexExpression(
-      ChangeBuilder builder, IndexExpression section) async {
-    var cascadeOperator = section.period;
-    var type = cascadeOperator.type;
-    if (type == TokenType.PERIOD_PERIOD) {
+  Future<void> _replaceFor(ChangeBuilder builder, Expression section) async {
+    if (section is AssignmentExpression) {
+      return _replaceFor(builder, section.leftHandSide);
+    }
+
+    if (section is IndexExpression) {
+      if (section.period != null) {
+        return _replaceToken(builder, section.period, _indexReplacement);
+      }
+      return _replaceFor(builder, section.target);
+    }
+
+    if (section is MethodInvocation) {
+      return _replaceToken(builder, section.operator, _propertyReplacement);
+    }
+
+    if (section is PropertyAccess) {
+      return _replaceToken(builder, section.operator, _propertyReplacement);
+    }
+  }
+
+  Future<void> _replaceToken(
+    ChangeBuilder builder,
+    Token token,
+    Map<TokenType, String> map,
+  ) async {
+    var replacement = map[token.type];
+    if (replacement != null) {
       await builder.addDartFileEdit(file, (builder) {
-        builder.addDeletion(
-            range.startStart(cascadeOperator, section.leftBracket));
-      });
-    } else if (type == TokenType.QUESTION_PERIOD_PERIOD) {
-      await builder.addDartFileEdit(file, (builder) {
-        builder.addSimpleReplacement(range.token(cascadeOperator), '?');
+        builder.addSimpleReplacement(range.token(token), replacement);
       });
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 332b3f5..83b5c92 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -176,6 +176,8 @@
       "Add required argument '{0}'");
   static const ADD_NE_NULL = FixKind('dart.fix.add.neNull', 50, 'Add != null',
       appliedTogetherMessage: 'Add != null everywhere in file');
+  static const ADD_NULL_CHECK =
+      FixKind('dart.fix.add.nullCheck', 50, 'Add a null check (!)');
   static const ADD_OVERRIDE =
       FixKind('dart.fix.add.override', 50, "Add '@override' annotation");
   static const ADD_REQUIRED =
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index b971b29..17d2049 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -21,6 +21,7 @@
 import 'package:analysis_server/src/services/correction/dart/add_missing_parameter_named.dart';
 import 'package:analysis_server/src/services/correction/dart/add_missing_required_argument.dart';
 import 'package:analysis_server/src/services/correction/dart/add_ne_null.dart';
+import 'package:analysis_server/src/services/correction/dart/add_null_check.dart';
 import 'package:analysis_server/src/services/correction/dart/add_override.dart';
 import 'package:analysis_server/src/services/correction/dart/add_required.dart';
 import 'package:analysis_server/src/services/correction/dart/add_required_keyword.dart';
@@ -591,6 +592,7 @@
       MakeVariableNotFinal.newInstance,
     ],
     CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE: [
+      AddNullCheck.newInstance,
       WrapInText.newInstance,
     ],
     CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT: [
@@ -673,6 +675,7 @@
     ],
     CompileTimeErrorCode.INVALID_ASSIGNMENT: [
       AddExplicitCast.newInstance,
+      AddNullCheck.newInstance,
       ChangeTypeAnnotation.newInstance,
     ],
     CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION: [
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 39e8891..de1b34ac 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -441,7 +441,6 @@
   String describe(AnalysisOptionsImpl options) {
     var b = StringBuffer();
 
-    b.write(writeOption('Strong mode', options.strongMode));
     b.write(writeOption('Implicit dynamic', options.implicitDynamic));
     b.write(writeOption('Implicit casts', options.implicitCasts));
     b.write(writeOption('Feature set', options.contextFeatures.toString()));
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index d9bd015..715556b 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -599,6 +599,7 @@
             isTrue);
       });
     }
+    return Future.value(null);
   }
 
   Future<void> test_invocation_withTrailingStmt() {
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
index eb61712..dc2b461 100644
--- a/pkg/analysis_server/test/lsp/completion_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_test.dart
@@ -352,6 +352,29 @@
     expect(item.detail, isNot(contains('deprecated')));
   }
 
+  Future<void> test_namedArg_offsetBeforeCompletionTarget() async {
+    // This test checks for a previous bug where the completion target was a
+    // symbol far after the cursor offset (`aaaa` here) and caused the whole
+    // identifier to be used as the `targetPrefix` which would filter out
+    // other symbol.
+    // https://github.com/Dart-Code/Dart-Code/issues/2672#issuecomment-666085575
+    final content = '''
+    void main() {
+      myFunction(
+        ^
+        aaaa: '',
+      );
+    }
+
+    void myFunction({String aaaa, String aaab, String aaac}) {}
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'aaab: '), isTrue);
+  }
+
   Future<void> test_namedArg_plainText() async {
     final content = '''
     class A { const A({int one}); }
diff --git a/pkg/analysis_server/test/src/cider/completion_test.dart b/pkg/analysis_server/test/src/cider/completion_test.dart
index 48875ac..e8abf70 100644
--- a/pkg/analysis_server/test/src/cider/completion_test.dart
+++ b/pkg/analysis_server/test/src/cider/completion_test.dart
@@ -267,6 +267,22 @@
     _assertHasNamedArgument(name: 'bbb');
   }
 
+  Future<void> test_filterSort_namedArgument_noPrefix_beforeOther() async {
+    await _compute(r'''
+void foo({int aaa = 0, int aab = 0}) {}
+
+voif f() {
+  foo(
+    ^
+    aaa: 0,
+  );
+}
+
+''');
+
+    _assertHasNamedArgument(name: 'aab');
+  }
+
   Future<void> test_filterSort_preferLocal() async {
     await _compute(r'''
 var a = 0;
diff --git a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
index fc8eba5..d8b8b06 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
@@ -38,7 +38,7 @@
     if (expectedType == null) {
       expect(type, null);
     } else {
-      expect(type?.getDisplayString(), expectedType);
+      expect(type?.getDisplayString(withNullability: false), expectedType);
     }
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
index cdcb95c..115d78c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -12,6 +13,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AddExplicitCastTest);
+    defineReflectiveTests(AddExplicitCastWithNullSafetyTest);
   });
 }
 
@@ -474,3 +476,27 @@
     );
   }
 }
+
+@reflectiveTest
+class AddExplicitCastWithNullSafetyTest extends AddExplicitCastTest {
+  @override
+  List<String> get experiments => [EnableString.non_nullable];
+
+  Future<void> test_assignment_null() async {
+    await resolveTestUnit('''
+void f(int x) {
+  x = null;
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_assignment_nullable() async {
+    await resolveTestUnit('''
+void f(int x, int? y) {
+  x = y;
+}
+''');
+    await assertNoFix();
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
new file mode 100644
index 0000000..67c35f1
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_null_check_test.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AddNullCheckTest);
+  });
+}
+
+@reflectiveTest
+class AddNullCheckTest extends FixProcessorTest {
+  @override
+  List<String> get experiments => [EnableString.non_nullable];
+
+  @override
+  FixKind get kind => DartFixKind.ADD_NULL_CHECK;
+
+  Future<void> test_argument() async {
+    await resolveTestUnit('''
+void f(int x) {}
+void g(int? y) {
+  f(y);
+}
+''');
+    await assertHasFix('''
+void f(int x) {}
+void g(int? y) {
+  f(y!);
+}
+''');
+  }
+
+  Future<void> test_argument_differByMoreThanNullability() async {
+    await resolveTestUnit('''
+void f(int x) {}
+void g(String y) {
+  f(y);
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_assignment() async {
+    await resolveTestUnit('''
+void f(int x, int? y) {
+  x = y;
+}
+''');
+    await assertHasFix('''
+void f(int x, int? y) {
+  x = y!;
+}
+''');
+  }
+
+  Future<void>
+      test_assignment_differByMoreThanNullability_nonNullableRight() async {
+    await resolveTestUnit('''
+void f(int x, String y) {
+  x = y;
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void>
+      test_assignment_differByMoreThanNullability_nullableRight() async {
+    await resolveTestUnit('''
+void f(int x, String? y) {
+  x = y;
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_assignment_needsParens() async {
+    await resolveTestUnit('''
+void f(A x) {
+  x = x + x;
+}
+class A {
+  A? operator +(A a) => null;
+}
+''');
+    await assertHasFix('''
+void f(A x) {
+  x = (x + x)!;
+}
+class A {
+  A? operator +(A a) => null;
+}
+''');
+  }
+
+  Future<void> test_initializer() async {
+    await resolveTestUnit('''
+void f(int? x) {
+  int y = x;
+  print(y);
+}
+''');
+    await assertHasFix('''
+void f(int? x) {
+  int y = x!;
+  print(y);
+}
+''');
+  }
+
+  Future<void> test_initializer_differByMoreThanNullability() async {
+    await resolveTestUnit('''
+void f(String x) {
+  int y = x;
+  print(y);
+}
+''');
+    await assertNoFix();
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_test.dart
new file mode 100644
index 0000000..5933dbe
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/create_method_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AddMissingHashOrEqualsTest);
+  });
+}
+
+@reflectiveTest
+class AddMissingHashOrEqualsTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.hash_and_equals;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+class C {
+  @override
+  int get hashCode => 13;
+}
+
+class D {
+  @override
+  bool operator ==(Object other) => false;
+}
+''');
+    await assertHasFix('''
+class C {
+  @override
+  int get hashCode => 13;
+
+  @override
+  bool operator ==(Object other) {
+    // TODO: implement ==
+    return super == other;
+  }
+}
+
+class D {
+  @override
+  bool operator ==(Object other) => false;
+
+  @override
+  // TODO: implement hashCode
+  int get hashCode => super.hashCode;
+
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_test.dart
new file mode 100644
index 0000000..ea4c184
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_await_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveAwaitTest);
+  });
+}
+
+@reflectiveTest
+class RemoveAwaitTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.await_only_futures;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+f() async {
+  print(await 23);
+}
+
+f2() async {
+  print(await 'hola');
+}
+''');
+    await assertHasFix('''
+f() async {
+  print(23);
+}
+
+f2() async {
+  print('hola');
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_test.dart
new file mode 100644
index 0000000..0ce557d
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_duplicate_case_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveDuplicateCaseTest);
+  });
+}
+
+@reflectiveTest
+class RemoveDuplicateCaseTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.no_duplicate_case_values;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+void switchInt() {
+  switch (2) {
+    case 1:
+      print('a');
+      break;
+    case 2:
+    case 2:
+    case 3:
+    case 3:
+    default:
+      print('?');
+  }
+}
+''');
+    await assertHasFix('''
+void switchInt() {
+  switch (2) {
+    case 1:
+      print('a');
+      break;
+    case 2:
+    case 3:
+    default:
+      print('?');
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_test.dart
new file mode 100644
index 0000000..2582a53
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_catch_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveEmptyCatchTest);
+  });
+}
+
+@reflectiveTest
+class RemoveEmptyCatchTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.empty_catches;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+void f() {
+  try {
+    try {
+      1;
+    } catch (e) {} finally {}
+  } catch (e) {} finally {}
+}
+
+void f2() {
+  try {} catch (e) {} finally {}
+}
+''');
+    await assertHasFix('''
+void f() {
+  try {
+    try {
+      1;
+    } finally {}
+  } finally {}
+}
+
+void f2() {
+  try {} finally {}
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_test.dart
new file mode 100644
index 0000000..9272e89
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_constructor_body_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveEmptyConstructorBodyTest);
+  });
+}
+
+@reflectiveTest
+class RemoveEmptyConstructorBodyTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.empty_constructor_bodies;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+class C {
+  C() {}
+}
+
+class D {
+  D() {}
+}
+''');
+    await assertHasFix('''
+class C {
+  C();
+}
+
+class D {
+  D();
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_test.dart
new file mode 100644
index 0000000..42227c9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_empty_statement_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveEmptyStatementTest);
+  });
+}
+
+@reflectiveTest
+class RemoveEmptyStatementTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.empty_statements;
+
+  Future<void> test_singleFile() async {
+    // Note that ReplaceWithEmptyBrackets is not supported.
+    //   for example: `if (true) ;` ...
+    await resolveTestUnit('''
+void f() {
+  while(true) {
+    ;
+  }
+}
+
+void f2() {
+  while(true) { ; }
+}
+''');
+    await assertHasFix('''
+void f() {
+  while(true) {
+  }
+}
+
+void f2() {
+  while(true) { }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_test.dart
new file mode 100644
index 0000000..e8aede6
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_operator_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveOperatorTest);
+  });
+}
+
+@reflectiveTest
+class RemoveOperatorTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.prefer_adjacent_string_concatenation;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+var s = 'a' + 'b';
+var s1 = 'b' + 'c';
+''');
+    await assertHasFix('''
+var s = 'a' 'b';
+var s1 = 'b' 'c';
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_test.dart
new file mode 100644
index 0000000..f647efb
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_null_with_closure_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceNullWithClosureTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceNullWithClosureTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.null_closures;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+void f(List<int> l) {
+  l.firstWhere((e) => e.isEven, orElse: null);
+}
+
+void f2(String s) {
+  s.splitMapJoin('', onNonMatch: null);
+}
+''');
+    await assertHasFix('''
+void f(List<int> l) {
+  l.firstWhere((e) => e.isEven, orElse: () => null);
+}
+
+void f2(String s) {
+  s.splitMapJoin('', onNonMatch: (String p1) => null);
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_test.dart
new file mode 100644
index 0000000..63c23a5
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/replace_with_var_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceWithVarTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceWithVarTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.omit_local_variable_types;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+List f() {
+  List<int> l = [];
+  return l;
+}
+
+void f2(List<int> list) {
+  for (int i in list) {
+    print(i);
+  }
+}
+''');
+    await assertHasFix('''
+List f() {
+  var l = <int>[];
+  return l;
+}
+
+void f2(List<int> list) {
+  for (var i in list) {
+    print(i);
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index e2f2972..75eea74 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -8,25 +8,46 @@
 import 'convert_documentation_into_line_test.dart'
     as convert_documentation_into_line;
 import 'convert_to_contains_test.dart' as convert_to_contains;
+import 'create_method_test.dart' as create_method;
 import 'remove_argument_test.dart' as remove_argument;
+import 'remove_await_test.dart' as remove_await;
+import 'remove_duplicate_case_test.dart' as remove_duplicate_case;
+import 'remove_empty_catch_test.dart' as remove_empty_catch;
+import 'remove_empty_constructor_body_test.dart'
+    as remove_empty_constructor_body;
 import 'remove_empty_else_test.dart' as remove_empty_else;
+import 'remove_empty_statement_test.dart' as remove_empty_statement;
 import 'remove_initializer_test.dart' as remove_initializer;
+import 'remove_operator_test.dart' as remove_operator;
 import 'remove_type_annotation_test.dart' as remove_type_annotation;
 import 'remove_unnecessary_const_test.dart' as remove_unnecessary_const;
 import 'remove_unnecessary_new_test.dart' as remove_unnecessary_new;
 import 'replace_colon_with_equals_test.dart' as replace_colon_with_equals;
+import 'replace_null_with_closure_test.dart' as replace_null_with_closure;
+import 'replace_with_var_test.dart' as replace_with_var;
+import 'use_curly_braces_test.dart' as use_curly_braces;
 
 void main() {
   defineReflectiveSuite(() {
     add_override.main();
     convert_documentation_into_line.main();
     convert_to_contains.main();
+    create_method.main();
     remove_argument.main();
+    remove_await.main();
+    remove_duplicate_case.main();
     remove_initializer.main();
+    remove_empty_catch.main();
+    remove_empty_constructor_body.main();
     remove_empty_else.main();
+    remove_empty_statement.main();
+    remove_operator.main();
     remove_type_annotation.main();
     remove_unnecessary_const.main();
     remove_unnecessary_new.main();
     replace_colon_with_equals.main();
+    replace_null_with_closure.main();
+    replace_with_var.main();
+    use_curly_braces.main();
   }, name: 'bulk');
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_test.dart
new file mode 100644
index 0000000..3bce118
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/use_curly_braces_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UseCurlyBracesTest);
+  });
+}
+
+@reflectiveTest
+class UseCurlyBracesTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.curly_braces_in_flow_control_structures;
+
+  Future<void> test_singleFile() async {
+    await resolveTestUnit('''
+f() {
+  while (true) if (false) print('');
+}
+
+f2() {
+  while (true) print(2);
+}
+''');
+    await assertHasFix('''
+f() {
+  while (true) if (false) {
+    print('');
+  }
+}
+
+f2() {
+  while (true) {
+    print(2);
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart
index 2317c0f..a010515 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_duplicate_case_test.dart
@@ -23,6 +23,40 @@
   @override
   String get lintCode => LintNames.no_duplicate_case_values;
 
+  Future<void> test_fallThroughFromPrevious() async {
+    await resolveTestUnit('''
+void switchInt() {
+  switch (2) {
+    case 1:
+      print('a');
+      break;
+    case 2:
+    case 3:
+    case 2:
+      print('b');
+      break;
+    default:
+      print('?');
+  }
+}
+''');
+    await assertHasFix('''
+void switchInt() {
+  switch (2) {
+    case 1:
+      print('a');
+      break;
+    case 2:
+    case 3:
+      print('b');
+      break;
+    default:
+      print('?');
+  }
+}
+''');
+  }
+
   Future<void> test_removeIntCase() async {
     await resolveTestUnit('''
 void switchInt() {
@@ -62,7 +96,7 @@
     case 'b':
       print('b');
       break;
-    case 'a' :
+    case 'a':
       print('a');
       break;
     default:
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart
index 28abf56..907e168 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_cascade_with_dot_test.dart
@@ -39,6 +39,26 @@
 ''');
   }
 
+  Future<void> test_assignment_index_propertyAccess_normalCascade() async {
+    await resolveTestUnit('''
+class A {
+  void foo() {
+    0..bar[1] = 2;
+  }
+}
+''');
+    await assertHasFix('''
+class A {
+  void foo() {
+    0.bar[1] = 2;
+  }
+}
+''',
+        errorFilter: (e) =>
+            e.errorCode.name ==
+            LintNames.avoid_single_cascade_in_expression_statements);
+  }
+
   Future<void> test_assignment_property_normalCascade() async {
     await resolveTestUnit('''
 void f(C c) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 32dd350..a65ca4c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -23,6 +23,7 @@
 import 'add_missing_required_argument_test.dart'
     as add_missing_required_argument;
 import 'add_ne_null_test.dart' as add_ne_null;
+import 'add_null_check_test.dart' as add_null_check;
 import 'add_override_test.dart' as add_override;
 import 'add_required_test.dart' as add_required;
 import 'add_return_type_test.dart' as add_return_type;
@@ -181,6 +182,7 @@
     add_missing_parameter_required.main();
     add_missing_required_argument.main();
     add_ne_null.main();
+    add_null_check.main();
     add_override.main();
     add_required.main();
     add_return_type.main();
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
index fef2206..843ac88 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
@@ -317,6 +317,24 @@
           equals('Supports deleting existing files and folders.'));
     });
 
+    test('parses an enum using keywords as identifiers', () {
+      final input = '''
+enum Foo {
+  namespace = 'namespace',
+  class = 'class',
+  enum = 'enum',
+}
+    ''';
+      final output = parseString(input);
+      expect(output, hasLength(1));
+      expect(output.first, const TypeMatcher<Namespace>());
+      final enum_ = output.first as Namespace;
+      expect(enum_.members, hasLength(3));
+      expect(enum_.members[0].name, equals('namespace'));
+      expect(enum_.members[1].name, equals('class'));
+      expect(enum_.members[2].name, equals('enum'));
+    });
+
     test('parses a tuple in an array', () {
       final input = '''
 interface SomeInformation {
diff --git a/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart b/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
index a2c0c4b..2c51ca3 100644
--- a/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
+++ b/pkg/analysis_server/tool/completion_metrics/implicit_type_declarations.dart
@@ -111,7 +111,10 @@
       var rhsType = node.initializer?.staticType;
       if (rhsType != null && !rhsType.isDynamic) {
         // Record the name with the type.
-        data.recordImpliedType(node.name.name, rhsType.getDisplayString());
+        data.recordImpliedType(
+          node.name.name,
+          rhsType.getDisplayString(withNullability: false),
+        );
       }
     }
   }
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index c9ec3cb..cefcce6 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -133,11 +133,13 @@
 
 /// Maps reserved words and identifiers that cause issues in field names.
 String _makeValidIdentifier(String identifier) {
-  // The SymbolKind class has uses these names which cause issues for code that
-  // uses them as types.
+  // Some identifiers used in LSP are reserved words in Dart, so map them to
+  // other values.
   const map = {
     'Object': 'Obj',
     'String': 'Str',
+    'class': 'class_',
+    'enum': 'enum_',
   };
   return map[identifier] ?? identifier;
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index de0b9b3..2f29b7f 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -298,5 +298,20 @@
     return false;
   }
 
+  // There are some example blocks that just contain arrays with no definitions.
+  // They're most easily noted by ending with `]` which no valid TypeScript blocks
+  // do.
+  if (input.trim().endsWith(']')) {
+    return false;
+  }
+
+  // There's a chunk of typescript that is just a partial snippet from a real
+  // interface declared elsewhere that we can only detect by the leading comment.
+  if (input
+      .replaceAll('\r', '')
+      .startsWith('/**\n\t * Window specific client capabilities.')) {
+    return false;
+  }
+
   return true;
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
index 8121590..1f510d6 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
@@ -13,6 +13,17 @@
 /// of type names for inline types.
 const fieldNameForIndexer = 'indexer';
 
+final _keywords = const <String, TokenType>{
+  'class': TokenType.CLASS_KEYWORD,
+  'const': TokenType.CONST_KEYWORD,
+  'enum': TokenType.ENUM_KEYWORD,
+  'export': TokenType.EXPORT_KEYWORD,
+  'extends': TokenType.EXTENDS_KEYWORD,
+  'interface': TokenType.INTERFACE_KEYWORD,
+  'namespace': TokenType.NAMESPACE_KEYWORD,
+  'readonly': TokenType.READONLY_KEYWORD,
+};
+
 final _validIdentifierCharacters = RegExp('[a-zA-Z0-9_]');
 
 bool isAnyType(TypeBase t) =>
@@ -246,6 +257,18 @@
       return _advance();
     }
 
+    // The scanner currently reads keywords with specific token types
+    // (eg. TokenType.NAMESPACE_KEYWORD) however v3.16 of the LSP spec also uses
+    // some of these words as identifiers. If the requested type is an identifier
+    // but we have a keyword token, then treat it as an identifier.
+    if (type == TokenType.IDENTIFIER) {
+      final next = !_isAtEnd ? _peek() : null;
+      if (_isKeyword(next?.type)) {
+        _advance();
+        return Token(TokenType.IDENTIFIER, next.lexeme);
+      }
+    }
+
     throw '$message\n\n${_peek()}';
   }
 
@@ -270,7 +293,6 @@
 
   Const _enumValue(String enumName) {
     final leadingComment = _comment();
-    _eatUnwantedKeywords();
     final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
     TypeBase type;
     if (_match([TokenType.COLON])) {
@@ -421,6 +443,8 @@
     return Interface(leadingComment, name, typeArgs, baseTypes, members);
   }
 
+  bool _isKeyword(TokenType type) => _keywords.values.contains(type);
+
   String _joinNames(String parent, String child) {
     return '$parent${capitalize(child)}';
   }
@@ -668,23 +692,13 @@
       : throw 'Cannot advance past end of source';
 
   void _identifier() {
-    const keywords = <String, TokenType>{
-      'class': TokenType.CLASS_KEYWORD,
-      'const': TokenType.CONST_KEYWORD,
-      'enum': TokenType.ENUM_KEYWORD,
-      'export': TokenType.EXPORT_KEYWORD,
-      'extends': TokenType.EXTENDS_KEYWORD,
-      'interface': TokenType.INTERFACE_KEYWORD,
-      'namespace': TokenType.NAMESPACE_KEYWORD,
-      'readonly': TokenType.READONLY_KEYWORD,
-    };
     while (_isAlpha(_peek())) {
       _advance();
     }
 
     final string = _source.substring(_startOfToken, _currentPos);
-    if (keywords.containsKey(string)) {
-      _addToken(keywords[string]);
+    if (_keywords.containsKey(string)) {
+      _addToken(_keywords[string]);
     } else {
       _addToken(TokenType.IDENTIFIER);
     }
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 9c29e83..6b9c72e 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.39.16-dev
+* Added `TypeVisitorWithArgument` and `DartType.acceptWithArgument`.
+* Bumped the analyzer's SDK requirement to `>=2.7.0`, so that extension methods
+  can be used within the analyzer implementation. Previously it was `2.6.0`,
+  but there is an [issue](https://github.com/dart-lang/sdk/issues/42888).
+
 ## 0.39.15
 * Move `asInstanceOf(ClassElement)` to `DartType`, so that it is also
   supported for `TypeParameterType` when its bound implements the
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 4258c77..62f4670 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -11,8 +11,6 @@
     omit_local_variable_types: ignore
     # There are currently 3360 violations in lib/.
     prefer_single_quotes: ignore
-    # There are currently 2000 violations in lib/.
-    unnecessary_this: ignore
 
     # "strict-inference" is enabled, but "unused" parameters named '_' are
     # still reported.  Re-evaluate after
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index e15d880..156470c 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -126,6 +126,12 @@
   /// Use the given [visitor] to visit this type.
   R accept<R>(TypeVisitor<R> visitor);
 
+  /// Use the given [visitor] to visit this type.
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  );
+
   /// Return the canonical interface that this type implements for [element],
   /// or `null` if such an interface does not exist.
   ///
diff --git a/pkg/analyzer/lib/dart/element/type_visitor.dart b/pkg/analyzer/lib/dart/element/type_visitor.dart
index d23115d..69ad90e 100644
--- a/pkg/analyzer/lib/dart/element/type_visitor.dart
+++ b/pkg/analyzer/lib/dart/element/type_visitor.dart
@@ -23,6 +23,25 @@
   R visitVoidType(VoidType type);
 }
 
+/// Interface for type visitors that have one argument.
+///
+/// Clients may not extend, implement, or mix-in this class.
+abstract class TypeVisitorWithArgument<R, A> {
+  const TypeVisitorWithArgument();
+
+  R visitDynamicType(DynamicType type, A argument);
+
+  R visitFunctionType(FunctionType type, A argument);
+
+  R visitInterfaceType(InterfaceType type, A argument);
+
+  R visitNeverType(NeverType type, A argument);
+
+  R visitTypeParameterType(TypeParameterType type, A argument);
+
+  R visitVoidType(VoidType type, A argument);
+}
+
 /// Invokes [visitDartType] from any other `visitXyz` method.
 ///
 /// Clients may extend this class.
@@ -50,3 +69,44 @@
   @override
   R visitVoidType(VoidType type) => visitDartType(type);
 }
+
+/// Invokes [visitDartType] from any other `visitXyz` method.
+///
+/// Clients may extend this class.
+abstract class UnifyingTypeVisitorWithArgument<R, A>
+    implements TypeVisitorWithArgument<R, A> {
+  const UnifyingTypeVisitorWithArgument();
+
+  /// By default other `visitXyz` methods invoke this method.
+  R visitDartType(DartType type, A argument);
+
+  @override
+  R visitDynamicType(DynamicType type, A argument) {
+    return visitDartType(type, argument);
+  }
+
+  @override
+  R visitFunctionType(FunctionType type, A argument) {
+    return visitDartType(type, argument);
+  }
+
+  @override
+  R visitInterfaceType(InterfaceType type, A argument) {
+    return visitDartType(type, argument);
+  }
+
+  @override
+  R visitNeverType(NeverType type, A argument) {
+    return visitDartType(type, argument);
+  }
+
+  @override
+  R visitTypeParameterType(TypeParameterType type, A argument) {
+    return visitDartType(type, argument);
+  }
+
+  @override
+  R visitVoidType(VoidType type, A argument) {
+    return visitDartType(type, argument);
+  }
+}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index c0096fc..e5f3230 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -60,9 +60,6 @@
   AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
   AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES,
   AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
-  CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
-  CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
-  CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
   CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
   CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
   CompileTimeErrorCode.AMBIGUOUS_EXPORT,
@@ -106,6 +103,7 @@
   CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION,
   CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS,
   CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
+  CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
@@ -122,6 +120,7 @@
   CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
   CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
   CompileTimeErrorCode.CONST_EVAL_TYPE_TYPE,
+  CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
   CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
   CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
   CompileTimeErrorCode
@@ -425,6 +424,7 @@
   CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED,
   CompileTimeErrorCode.URI_WITH_INTERPOLATION,
   CompileTimeErrorCode.USE_OF_VOID_RESULT,
+  CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
   CompileTimeErrorCode.WRONG_EXPLICIT_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
   CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
   CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
@@ -884,7 +884,7 @@
     String message = formatList(errorCode.message, arguments);
     String correctionTemplate = errorCode.correction;
     if (correctionTemplate != null) {
-      this._correction = formatList(correctionTemplate, arguments);
+      _correction = formatList(correctionTemplate, arguments);
     }
     _problemMessage = DiagnosticMessageImpl(
         filePath: source?.fullName,
diff --git a/pkg/analyzer/lib/error/listener.dart b/pkg/analyzer/lib/error/listener.dart
index e95548f..ffb3b98 100644
--- a/pkg/analyzer/lib/error/listener.dart
+++ b/pkg/analyzer/lib/error/listener.dart
@@ -67,7 +67,7 @@
     } else if (_defaultSource == null) {
       throw ArgumentError("A default source must be provided");
     }
-    this._source = _defaultSource;
+    _source = _defaultSource;
   }
 
   Source get source => _source;
@@ -76,7 +76,7 @@
   /// Setting the source to `null` will cause the default source to be used.
   @Deprecated('Create separate reporters for separate files')
   set source(Source source) {
-    this._source = source ?? _defaultSource;
+    _source = source ?? _defaultSource;
   }
 
   /// Report the given [error].
diff --git a/pkg/analyzer/lib/exception/exception.dart b/pkg/analyzer/lib/exception/exception.dart
index 8f3a1af..c666fbae 100644
--- a/pkg/analyzer/lib/exception/exception.dart
+++ b/pkg/analyzer/lib/exception/exception.dart
@@ -48,7 +48,7 @@
   /// [stackTrace], and [message].
   CaughtException.withMessage(
       this.message, this.exception, StackTrace stackTrace)
-      : this.stackTrace = stackTrace ?? StackTrace.current;
+      : stackTrace = stackTrace ?? StackTrace.current;
 
   /// Recursively unwrap this [CaughtException] if it itself contains a
   /// [CaughtException].
diff --git a/pkg/analyzer/lib/source/line_info.dart b/pkg/analyzer/lib/source/line_info.dart
index dbd0e2f..96c9149 100644
--- a/pkg/analyzer/lib/source/line_info.dart
+++ b/pkg/analyzer/lib/source/line_info.dart
@@ -47,7 +47,8 @@
   /// Return the location information for the character at the given [offset].
   ///
   /// A future version of this API will return a [CharacterLocation] rather than
-  /// a [LineInfo_Location]. // ignore: deprecated_member_use_from_same_package
+  // ignore: deprecated_member_use_from_same_package
+  /// a [LineInfo_Location].
   // ignore: deprecated_member_use_from_same_package
   LineInfo_Location getLocation(int offset) {
     var min = 0;
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index e5bb8c1..6b0199c 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -55,16 +55,34 @@
 }
 
 /// Use the command-line [args] to create a context builder.
-ContextBuilderOptions createContextBuilderOptions(ArgResults args) {
+ContextBuilderOptions createContextBuilderOptions(
+  ResourceProvider resourceProvider,
+  ArgResults args,
+) {
+  String absoluteNormalizedPath(String path) {
+    if (path == null) {
+      return null;
+    }
+    var pathContext = resourceProvider.pathContext;
+    return pathContext.normalize(
+      pathContext.absolute(path),
+    );
+  }
+
   ContextBuilderOptions builderOptions = ContextBuilderOptions();
   builderOptions.argResults = args;
   //
   // File locations.
   //
-  builderOptions.dartSdkSummaryPath = args[sdkSummaryPathOption];
-  builderOptions.defaultAnalysisOptionsFilePath =
-      args[analysisOptionsFileOption];
-  builderOptions.defaultPackageFilePath = args[packagesOption];
+  builderOptions.dartSdkSummaryPath = absoluteNormalizedPath(
+    args[sdkSummaryPathOption],
+  );
+  builderOptions.defaultAnalysisOptionsFilePath = absoluteNormalizedPath(
+    args[analysisOptionsFileOption],
+  );
+  builderOptions.defaultPackageFilePath = absoluteNormalizedPath(
+    args[packagesOption],
+  );
   //
   // Analysis options.
   //
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index e88e7e0..d536249 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -47,7 +47,7 @@
   /// supplied, it will be used to access the file system. Otherwise the default
   /// resource provider will be used.
   ContextLocatorImpl({ResourceProvider resourceProvider})
-      : this.resourceProvider =
+      : resourceProvider =
             resourceProvider ?? PhysicalResourceProvider.INSTANCE;
 
   @deprecated
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 1b5e12a..9faa830 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -296,7 +296,7 @@
   /// Return the signature of the file, based on API signatures of the
   /// transitive closure of imported / exported files.
   String get transitiveSignature {
-    this.libraryCycle; // sets _transitiveSignature
+    libraryCycle; // sets _transitiveSignature
     return _transitiveSignature;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index e20331c..3f4b76a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -65,9 +65,9 @@
     @required SourceFactory sourceFactory,
     @required this.externalSummaries,
     @required FileState targetLibrary,
-  })  : this.logger = logger,
-        this.byteStore = byteStore,
-        this.analysisSession = session {
+  })  : logger = logger,
+        byteStore = byteStore,
+        analysisSession = session {
     var synchronousSession =
         SynchronousSession(analysisOptions, declaredVariables);
     analysisContext = AnalysisContextImpl(synchronousSession, sourceFactory);
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 055f715..d343115 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -231,7 +231,7 @@
   AnalysisOptionsImpl get analysisOptions => _analysisOptions;
 
   set analysisOptions(AnalysisOptionsImpl analysisOptions) {
-    this._analysisOptions = analysisOptions;
+    _analysisOptions = analysisOptions;
 
     _typeSystemLegacy?.updateOptions(
       implicitCasts: analysisOptions.implicitCasts,
diff --git a/pkg/analyzer/lib/src/dart/ast/extensions.dart b/pkg/analyzer/lib/src/dart/ast/extensions.dart
index a7da188..fd66ae4 100644
--- a/pkg/analyzer/lib/src/dart/ast/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/ast/extensions.dart
@@ -7,6 +7,6 @@
 
 extension ListOfFormalParameterExtension on List<FormalParameter> {
   Iterable<FormalParameterImpl> get asImpl {
-    return this.cast<FormalParameterImpl>();
+    return cast<FormalParameterImpl>();
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 30e603e..3867938 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -2437,8 +2437,8 @@
   /// node within an AST structure that corresponds to the given range of
   /// characters (between the [startOffset] and [endOffset] in the source.
   NodeLocator(int startOffset, [int endOffset])
-      : this._startOffset = startOffset,
-        this._endOffset = endOffset ?? startOffset;
+      : _startOffset = startOffset,
+        _endOffset = endOffset ?? startOffset;
 
   /// Return the node that was found that corresponds to the given source range
   /// or `null` if there is no such node.
@@ -2530,8 +2530,8 @@
   /// If [endOffset] is not provided, then it is considered the same as the
   /// given [startOffset].
   NodeLocator2(int startOffset, [int endOffset])
-      : this._startOffset = startOffset,
-        this._endOffset = endOffset ?? startOffset;
+      : _startOffset = startOffset,
+        _endOffset = endOffset ?? startOffset;
 
   /// Search within the given AST [node] and return the node that was found,
   /// or `null` if no node was found.
@@ -3978,7 +3978,7 @@
 
   @override
   bool visitAdjacentStrings(AdjacentStrings node) {
-    AdjacentStrings toNode = this._toNode as AdjacentStrings;
+    AdjacentStrings toNode = _toNode as AdjacentStrings;
     if (_isEqualNodeLists(node.strings, toNode.strings)) {
       toNode.staticType = node.staticType;
       return true;
@@ -3988,7 +3988,7 @@
 
   @override
   bool visitAnnotation(Annotation node) {
-    Annotation toNode = this._toNode as Annotation;
+    Annotation toNode = _toNode as Annotation;
     if (_and(
         _isEqualTokens(node.atSign, toNode.atSign),
         _isEqualNodes(node.name, toNode.name),
@@ -4003,7 +4003,7 @@
 
   @override
   bool visitArgumentList(ArgumentList node) {
-    ArgumentList toNode = this._toNode as ArgumentList;
+    ArgumentList toNode = _toNode as ArgumentList;
     return _and(
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodeLists(node.arguments, toNode.arguments),
@@ -4012,7 +4012,7 @@
 
   @override
   bool visitAsExpression(AsExpression node) {
-    AsExpression toNode = this._toNode as AsExpression;
+    AsExpression toNode = _toNode as AsExpression;
     if (_and(
         _isEqualNodes(node.expression, toNode.expression),
         _isEqualTokens(node.asOperator, toNode.asOperator),
@@ -4025,7 +4025,7 @@
 
   @override
   bool visitAssertInitializer(AssertInitializer node) {
-    AssertInitializer toNode = this._toNode as AssertInitializer;
+    AssertInitializer toNode = _toNode as AssertInitializer;
     return _and(
         _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -4037,7 +4037,7 @@
 
   @override
   bool visitAssertStatement(AssertStatement node) {
-    AssertStatement toNode = this._toNode as AssertStatement;
+    AssertStatement toNode = _toNode as AssertStatement;
     return _and(
         _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -4050,7 +4050,7 @@
 
   @override
   bool visitAssignmentExpression(AssignmentExpression node) {
-    AssignmentExpression toNode = this._toNode as AssignmentExpression;
+    AssignmentExpression toNode = _toNode as AssignmentExpression;
     if (_and(
         _isEqualNodes(node.leftHandSide, toNode.leftHandSide),
         _isEqualTokens(node.operator, toNode.operator),
@@ -4064,7 +4064,7 @@
 
   @override
   bool visitAwaitExpression(AwaitExpression node) {
-    AwaitExpression toNode = this._toNode as AwaitExpression;
+    AwaitExpression toNode = _toNode as AwaitExpression;
     if (_and(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
         _isEqualNodes(node.expression, toNode.expression))) {
       toNode.staticType = node.staticType;
@@ -4075,7 +4075,7 @@
 
   @override
   bool visitBinaryExpression(BinaryExpression node) {
-    BinaryExpression toNode = this._toNode as BinaryExpression;
+    BinaryExpression toNode = _toNode as BinaryExpression;
     if (_and(
         _isEqualNodes(node.leftOperand, toNode.leftOperand),
         _isEqualTokens(node.operator, toNode.operator),
@@ -4089,7 +4089,7 @@
 
   @override
   bool visitBlock(Block node) {
-    Block toNode = this._toNode as Block;
+    Block toNode = _toNode as Block;
     return _and(
         _isEqualTokens(node.leftBracket, toNode.leftBracket),
         _isEqualNodeLists(node.statements, toNode.statements),
@@ -4098,13 +4098,13 @@
 
   @override
   bool visitBlockFunctionBody(BlockFunctionBody node) {
-    BlockFunctionBody toNode = this._toNode as BlockFunctionBody;
+    BlockFunctionBody toNode = _toNode as BlockFunctionBody;
     return _isEqualNodes(node.block, toNode.block);
   }
 
   @override
   bool visitBooleanLiteral(BooleanLiteral node) {
-    BooleanLiteral toNode = this._toNode as BooleanLiteral;
+    BooleanLiteral toNode = _toNode as BooleanLiteral;
     if (_and(_isEqualTokens(node.literal, toNode.literal),
         node.value == toNode.value)) {
       toNode.staticType = node.staticType;
@@ -4115,7 +4115,7 @@
 
   @override
   bool visitBreakStatement(BreakStatement node) {
-    BreakStatement toNode = this._toNode as BreakStatement;
+    BreakStatement toNode = _toNode as BreakStatement;
     if (_and(
         _isEqualTokens(node.breakKeyword, toNode.breakKeyword),
         _isEqualNodes(node.label, toNode.label),
@@ -4128,7 +4128,7 @@
 
   @override
   bool visitCascadeExpression(CascadeExpression node) {
-    CascadeExpression toNode = this._toNode as CascadeExpression;
+    CascadeExpression toNode = _toNode as CascadeExpression;
     if (_and(_isEqualNodes(node.target, toNode.target),
         _isEqualNodeLists(node.cascadeSections, toNode.cascadeSections))) {
       toNode.staticType = node.staticType;
@@ -4139,7 +4139,7 @@
 
   @override
   bool visitCatchClause(CatchClause node) {
-    CatchClause toNode = this._toNode as CatchClause;
+    CatchClause toNode = _toNode as CatchClause;
     return _and(
         _isEqualTokens(node.onKeyword, toNode.onKeyword),
         _isEqualNodes(node.exceptionType, toNode.exceptionType),
@@ -4154,7 +4154,7 @@
 
   @override
   bool visitClassDeclaration(ClassDeclaration node) {
-    ClassDeclaration toNode = this._toNode as ClassDeclaration;
+    ClassDeclaration toNode = _toNode as ClassDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4172,7 +4172,7 @@
 
   @override
   bool visitClassTypeAlias(ClassTypeAlias node) {
-    ClassTypeAlias toNode = this._toNode as ClassTypeAlias;
+    ClassTypeAlias toNode = _toNode as ClassTypeAlias;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4189,20 +4189,20 @@
 
   @override
   bool visitComment(Comment node) {
-    Comment toNode = this._toNode as Comment;
+    Comment toNode = _toNode as Comment;
     return _isEqualNodeLists(node.references, toNode.references);
   }
 
   @override
   bool visitCommentReference(CommentReference node) {
-    CommentReference toNode = this._toNode as CommentReference;
+    CommentReference toNode = _toNode as CommentReference;
     return _and(_isEqualTokens(node.newKeyword, toNode.newKeyword),
         _isEqualNodes(node.identifier, toNode.identifier));
   }
 
   @override
   bool visitCompilationUnit(CompilationUnit node) {
-    CompilationUnit toNode = this._toNode as CompilationUnit;
+    CompilationUnit toNode = _toNode as CompilationUnit;
     if (_and(
         _isEqualTokens(node.beginToken, toNode.beginToken),
         _isEqualNodes(node.scriptTag, toNode.scriptTag),
@@ -4217,7 +4217,7 @@
 
   @override
   bool visitConditionalExpression(ConditionalExpression node) {
-    ConditionalExpression toNode = this._toNode as ConditionalExpression;
+    ConditionalExpression toNode = _toNode as ConditionalExpression;
     if (_and(
         _isEqualNodes(node.condition, toNode.condition),
         _isEqualTokens(node.question, toNode.question),
@@ -4232,7 +4232,7 @@
 
   @override
   bool visitConfiguration(Configuration node) {
-    Configuration toNode = this._toNode as Configuration;
+    Configuration toNode = _toNode as Configuration;
     if (_and(
         _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -4248,7 +4248,7 @@
 
   @override
   bool visitConstructorDeclaration(ConstructorDeclaration node) {
-    ConstructorDeclarationImpl toNode = this._toNode as ConstructorDeclaration;
+    ConstructorDeclarationImpl toNode = _toNode as ConstructorDeclaration;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4271,8 +4271,7 @@
 
   @override
   bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    ConstructorFieldInitializer toNode =
-        this._toNode as ConstructorFieldInitializer;
+    ConstructorFieldInitializer toNode = _toNode as ConstructorFieldInitializer;
     return _and(
         _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
         _isEqualTokens(node.period, toNode.period),
@@ -4283,7 +4282,7 @@
 
   @override
   bool visitConstructorName(ConstructorName node) {
-    ConstructorName toNode = this._toNode as ConstructorName;
+    ConstructorName toNode = _toNode as ConstructorName;
     if (_and(
         _isEqualNodes(node.type, toNode.type),
         _isEqualTokens(node.period, toNode.period),
@@ -4296,7 +4295,7 @@
 
   @override
   bool visitContinueStatement(ContinueStatement node) {
-    ContinueStatement toNode = this._toNode as ContinueStatement;
+    ContinueStatement toNode = _toNode as ContinueStatement;
     if (_and(
         _isEqualTokens(node.continueKeyword, toNode.continueKeyword),
         _isEqualNodes(node.label, toNode.label),
@@ -4309,7 +4308,7 @@
 
   @override
   bool visitDeclaredIdentifier(DeclaredIdentifier node) {
-    DeclaredIdentifier toNode = this._toNode as DeclaredIdentifier;
+    DeclaredIdentifier toNode = _toNode as DeclaredIdentifier;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4320,7 +4319,7 @@
 
   @override
   bool visitDefaultFormalParameter(covariant DefaultFormalParameterImpl node) {
-    var toNode = this._toNode as DefaultFormalParameterImpl;
+    var toNode = _toNode as DefaultFormalParameterImpl;
     return _and(
         _isEqualNodes(node.parameter, toNode.parameter),
         node.kind == toNode.kind,
@@ -4330,7 +4329,7 @@
 
   @override
   bool visitDoStatement(DoStatement node) {
-    DoStatement toNode = this._toNode as DoStatement;
+    DoStatement toNode = _toNode as DoStatement;
     return _and(
         _isEqualTokens(node.doKeyword, toNode.doKeyword),
         _isEqualNodes(node.body, toNode.body),
@@ -4343,13 +4342,13 @@
 
   @override
   bool visitDottedName(DottedName node) {
-    DottedName toNode = this._toNode as DottedName;
+    DottedName toNode = _toNode as DottedName;
     return _isEqualNodeLists(node.components, toNode.components);
   }
 
   @override
   bool visitDoubleLiteral(DoubleLiteral node) {
-    DoubleLiteral toNode = this._toNode as DoubleLiteral;
+    DoubleLiteral toNode = _toNode as DoubleLiteral;
     if (_and(_isEqualTokens(node.literal, toNode.literal),
         node.value == toNode.value)) {
       toNode.staticType = node.staticType;
@@ -4360,19 +4359,19 @@
 
   @override
   bool visitEmptyFunctionBody(EmptyFunctionBody node) {
-    EmptyFunctionBody toNode = this._toNode as EmptyFunctionBody;
+    EmptyFunctionBody toNode = _toNode as EmptyFunctionBody;
     return _isEqualTokens(node.semicolon, toNode.semicolon);
   }
 
   @override
   bool visitEmptyStatement(EmptyStatement node) {
-    EmptyStatement toNode = this._toNode as EmptyStatement;
+    EmptyStatement toNode = _toNode as EmptyStatement;
     return _isEqualTokens(node.semicolon, toNode.semicolon);
   }
 
   @override
   bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    EnumConstantDeclaration toNode = this._toNode as EnumConstantDeclaration;
+    EnumConstantDeclaration toNode = _toNode as EnumConstantDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4381,7 +4380,7 @@
 
   @override
   bool visitEnumDeclaration(EnumDeclaration node) {
-    EnumDeclaration toNode = this._toNode as EnumDeclaration;
+    EnumDeclaration toNode = _toNode as EnumDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4394,7 +4393,7 @@
 
   @override
   bool visitExportDirective(ExportDirective node) {
-    ExportDirective toNode = this._toNode as ExportDirective;
+    ExportDirective toNode = _toNode as ExportDirective;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4410,7 +4409,7 @@
 
   @override
   bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    ExpressionFunctionBody toNode = this._toNode as ExpressionFunctionBody;
+    ExpressionFunctionBody toNode = _toNode as ExpressionFunctionBody;
     return _and(
         _isEqualTokens(node.functionDefinition, toNode.functionDefinition),
         _isEqualNodes(node.expression, toNode.expression),
@@ -4419,21 +4418,21 @@
 
   @override
   bool visitExpressionStatement(ExpressionStatement node) {
-    ExpressionStatement toNode = this._toNode as ExpressionStatement;
+    ExpressionStatement toNode = _toNode as ExpressionStatement;
     return _and(_isEqualNodes(node.expression, toNode.expression),
         _isEqualTokens(node.semicolon, toNode.semicolon));
   }
 
   @override
   bool visitExtendsClause(ExtendsClause node) {
-    ExtendsClause toNode = this._toNode as ExtendsClause;
+    ExtendsClause toNode = _toNode as ExtendsClause;
     return _and(_isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
         _isEqualNodes(node.superclass, toNode.superclass));
   }
 
   @override
   bool visitExtensionDeclaration(ExtensionDeclaration node) {
-    ExtensionDeclaration toNode = this._toNode as ExtensionDeclaration;
+    ExtensionDeclaration toNode = _toNode as ExtensionDeclaration;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4452,7 +4451,7 @@
 
   @override
   bool visitExtensionOverride(ExtensionOverride node) {
-    ExtensionOverride toNode = this._toNode as ExtensionOverride;
+    ExtensionOverride toNode = _toNode as ExtensionOverride;
     return _and(
         _isEqualNodes(node.extensionName, toNode.extensionName),
         _isEqualNodes(node.typeArguments, toNode.typeArguments),
@@ -4461,7 +4460,7 @@
 
   @override
   bool visitFieldDeclaration(FieldDeclaration node) {
-    FieldDeclaration toNode = this._toNode as FieldDeclaration;
+    FieldDeclaration toNode = _toNode as FieldDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4472,7 +4471,7 @@
 
   @override
   bool visitFieldFormalParameter(FieldFormalParameter node) {
-    FieldFormalParameter toNode = this._toNode as FieldFormalParameter;
+    FieldFormalParameter toNode = _toNode as FieldFormalParameter;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4485,8 +4484,7 @@
 
   @override
   bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
-    ForEachPartsWithDeclaration toNode =
-        this._toNode as ForEachPartsWithDeclaration;
+    ForEachPartsWithDeclaration toNode = _toNode as ForEachPartsWithDeclaration;
     return _and(
         _isEqualNodes(node.loopVariable, toNode.loopVariable),
         _isEqualTokens(node.inKeyword, toNode.inKeyword),
@@ -4495,8 +4493,7 @@
 
   @override
   bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
-    ForEachPartsWithIdentifier toNode =
-        this._toNode as ForEachPartsWithIdentifier;
+    ForEachPartsWithIdentifier toNode = _toNode as ForEachPartsWithIdentifier;
     return _and(
         _isEqualNodes(node.identifier, toNode.identifier),
         _isEqualTokens(node.inKeyword, toNode.inKeyword),
@@ -4505,7 +4502,7 @@
 
   @override
   bool visitForElement(ForElement node) {
-    ForElement toNode = this._toNode as ForElement;
+    ForElement toNode = _toNode as ForElement;
     return _and(
         _isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
         _isEqualTokens(node.forKeyword, toNode.forKeyword),
@@ -4517,7 +4514,7 @@
 
   @override
   bool visitFormalParameterList(FormalParameterList node) {
-    FormalParameterList toNode = this._toNode as FormalParameterList;
+    FormalParameterList toNode = _toNode as FormalParameterList;
     return _and(
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodeLists(node.parameters, toNode.parameters),
@@ -4528,7 +4525,7 @@
 
   @override
   bool visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
-    ForPartsWithDeclarations toNode = this._toNode as ForPartsWithDeclarations;
+    ForPartsWithDeclarations toNode = _toNode as ForPartsWithDeclarations;
     return _and(
         _isEqualNodes(node.variables, toNode.variables),
         _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
@@ -4539,7 +4536,7 @@
 
   @override
   bool visitForPartsWithExpression(ForPartsWithExpression node) {
-    ForPartsWithExpression toNode = this._toNode as ForPartsWithExpression;
+    ForPartsWithExpression toNode = _toNode as ForPartsWithExpression;
     return _and(
         _isEqualNodes(node.initialization, toNode.initialization),
         _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
@@ -4550,7 +4547,7 @@
 
   @override
   bool visitForStatement(ForStatement node) {
-    ForStatement toNode = this._toNode as ForStatement;
+    ForStatement toNode = _toNode as ForStatement;
     return _and(
         _isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
         _isEqualTokens(node.forKeyword, toNode.forKeyword),
@@ -4562,7 +4559,7 @@
 
   @override
   bool visitFunctionDeclaration(FunctionDeclaration node) {
-    FunctionDeclaration toNode = this._toNode as FunctionDeclaration;
+    FunctionDeclaration toNode = _toNode as FunctionDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4576,13 +4573,13 @@
   @override
   bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
     FunctionDeclarationStatement toNode =
-        this._toNode as FunctionDeclarationStatement;
+        _toNode as FunctionDeclarationStatement;
     return _isEqualNodes(node.functionDeclaration, toNode.functionDeclaration);
   }
 
   @override
   bool visitFunctionExpression(FunctionExpression node) {
-    FunctionExpressionImpl toNode = this._toNode as FunctionExpression;
+    FunctionExpressionImpl toNode = _toNode as FunctionExpression;
     if (_and(_isEqualNodes(node.parameters, toNode.parameters),
         _isEqualNodes(node.body, toNode.body))) {
       toNode.declaredElement = node.declaredElement;
@@ -4595,7 +4592,7 @@
   @override
   bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     FunctionExpressionInvocation toNode =
-        this._toNode as FunctionExpressionInvocation;
+        _toNode as FunctionExpressionInvocation;
     if (_and(
         _isEqualNodes(node.function, toNode.function),
         _isEqualNodes(node.typeArguments, toNode.typeArguments),
@@ -4610,7 +4607,7 @@
 
   @override
   bool visitFunctionTypeAlias(FunctionTypeAlias node) {
-    FunctionTypeAlias toNode = this._toNode as FunctionTypeAlias;
+    FunctionTypeAlias toNode = _toNode as FunctionTypeAlias;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4625,7 +4622,7 @@
   @override
   bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     FunctionTypedFormalParameter toNode =
-        this._toNode as FunctionTypedFormalParameter;
+        _toNode as FunctionTypedFormalParameter;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4636,7 +4633,7 @@
 
   @override
   bool visitGenericFunctionType(GenericFunctionType node) {
-    GenericFunctionTypeImpl toNode = this._toNode as GenericFunctionTypeImpl;
+    GenericFunctionTypeImpl toNode = _toNode as GenericFunctionTypeImpl;
     if (_and(
         _isEqualNodes(node.returnType, toNode.returnType),
         _isEqualTokens(node.functionKeyword, toNode.functionKeyword),
@@ -4651,7 +4648,7 @@
 
   @override
   bool visitGenericTypeAlias(GenericTypeAlias node) {
-    GenericTypeAliasImpl toNode = this._toNode as GenericTypeAliasImpl;
+    GenericTypeAliasImpl toNode = _toNode as GenericTypeAliasImpl;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4668,14 +4665,14 @@
 
   @override
   bool visitHideCombinator(HideCombinator node) {
-    HideCombinator toNode = this._toNode as HideCombinator;
+    HideCombinator toNode = _toNode as HideCombinator;
     return _and(_isEqualTokens(node.keyword, toNode.keyword),
         _isEqualNodeLists(node.hiddenNames, toNode.hiddenNames));
   }
 
   @override
   bool visitIfElement(IfElement node) {
-    IfElement toNode = this._toNode as IfElement;
+    IfElement toNode = _toNode as IfElement;
     return _and(
         _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -4688,7 +4685,7 @@
 
   @override
   bool visitIfStatement(IfStatement node) {
-    IfStatement toNode = this._toNode as IfStatement;
+    IfStatement toNode = _toNode as IfStatement;
     return _and(
         _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -4701,7 +4698,7 @@
 
   @override
   bool visitImplementsClause(ImplementsClause node) {
-    ImplementsClause toNode = this._toNode as ImplementsClause;
+    ImplementsClause toNode = _toNode as ImplementsClause;
     return _and(
         _isEqualTokens(node.implementsKeyword, toNode.implementsKeyword),
         _isEqualNodeLists(node.interfaces, toNode.interfaces));
@@ -4709,7 +4706,7 @@
 
   @override
   bool visitImportDirective(ImportDirective node) {
-    ImportDirective toNode = this._toNode as ImportDirective;
+    ImportDirective toNode = _toNode as ImportDirective;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4727,7 +4724,7 @@
 
   @override
   bool visitIndexExpression(IndexExpression node) {
-    IndexExpression toNode = this._toNode as IndexExpression;
+    IndexExpression toNode = _toNode as IndexExpression;
     if (_and(
         _isEqualNodes(node.target, toNode.target),
         _isEqualTokens(node.leftBracket, toNode.leftBracket),
@@ -4743,8 +4740,7 @@
 
   @override
   bool visitInstanceCreationExpression(InstanceCreationExpression node) {
-    InstanceCreationExpression toNode =
-        this._toNode as InstanceCreationExpression;
+    InstanceCreationExpression toNode = _toNode as InstanceCreationExpression;
     if (_and(
         _isEqualTokens(node.keyword, toNode.keyword),
         _isEqualNodes(node.constructorName, toNode.constructorName),
@@ -4757,7 +4753,7 @@
 
   @override
   bool visitIntegerLiteral(IntegerLiteral node) {
-    IntegerLiteral toNode = this._toNode as IntegerLiteral;
+    IntegerLiteral toNode = _toNode as IntegerLiteral;
     if (_and(_isEqualTokens(node.literal, toNode.literal),
         node.value == toNode.value)) {
       toNode.staticType = node.staticType;
@@ -4768,7 +4764,7 @@
 
   @override
   bool visitInterpolationExpression(InterpolationExpression node) {
-    InterpolationExpression toNode = this._toNode as InterpolationExpression;
+    InterpolationExpression toNode = _toNode as InterpolationExpression;
     return _and(
         _isEqualTokens(node.leftBracket, toNode.leftBracket),
         _isEqualNodes(node.expression, toNode.expression),
@@ -4777,14 +4773,14 @@
 
   @override
   bool visitInterpolationString(InterpolationString node) {
-    InterpolationString toNode = this._toNode as InterpolationString;
+    InterpolationString toNode = _toNode as InterpolationString;
     return _and(_isEqualTokens(node.contents, toNode.contents),
         node.value == toNode.value);
   }
 
   @override
   bool visitIsExpression(IsExpression node) {
-    IsExpression toNode = this._toNode as IsExpression;
+    IsExpression toNode = _toNode as IsExpression;
     if (_and(
         _isEqualNodes(node.expression, toNode.expression),
         _isEqualTokens(node.isOperator, toNode.isOperator),
@@ -4798,21 +4794,21 @@
 
   @override
   bool visitLabel(Label node) {
-    Label toNode = this._toNode as Label;
+    Label toNode = _toNode as Label;
     return _and(_isEqualNodes(node.label, toNode.label),
         _isEqualTokens(node.colon, toNode.colon));
   }
 
   @override
   bool visitLabeledStatement(LabeledStatement node) {
-    LabeledStatement toNode = this._toNode as LabeledStatement;
+    LabeledStatement toNode = _toNode as LabeledStatement;
     return _and(_isEqualNodeLists(node.labels, toNode.labels),
         _isEqualNodes(node.statement, toNode.statement));
   }
 
   @override
   bool visitLibraryDirective(LibraryDirective node) {
-    LibraryDirective toNode = this._toNode as LibraryDirective;
+    LibraryDirective toNode = _toNode as LibraryDirective;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4827,7 +4823,7 @@
 
   @override
   bool visitLibraryIdentifier(LibraryIdentifier node) {
-    LibraryIdentifier toNode = this._toNode as LibraryIdentifier;
+    LibraryIdentifier toNode = _toNode as LibraryIdentifier;
     if (_isEqualNodeLists(node.components, toNode.components)) {
       toNode.staticType = node.staticType;
       return true;
@@ -4837,7 +4833,7 @@
 
   @override
   bool visitListLiteral(ListLiteral node) {
-    ListLiteral toNode = this._toNode as ListLiteral;
+    ListLiteral toNode = _toNode as ListLiteral;
     if (_and(
         _isEqualTokens(node.constKeyword, toNode.constKeyword),
         _isEqualNodes(node.typeArguments, toNode.typeArguments),
@@ -4852,7 +4848,7 @@
 
   @override
   bool visitMapLiteralEntry(MapLiteralEntry node) {
-    MapLiteralEntry toNode = this._toNode as MapLiteralEntry;
+    MapLiteralEntry toNode = _toNode as MapLiteralEntry;
     return _and(
         _isEqualNodes(node.key, toNode.key),
         _isEqualTokens(node.separator, toNode.separator),
@@ -4861,7 +4857,7 @@
 
   @override
   bool visitMethodDeclaration(MethodDeclaration node) {
-    MethodDeclaration toNode = this._toNode as MethodDeclaration;
+    MethodDeclaration toNode = _toNode as MethodDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4877,7 +4873,7 @@
 
   @override
   bool visitMethodInvocation(MethodInvocation node) {
-    MethodInvocation toNode = this._toNode as MethodInvocation;
+    MethodInvocation toNode = _toNode as MethodInvocation;
     if (_and(
         _isEqualNodes(node.target, toNode.target),
         _isEqualTokens(node.operator, toNode.operator),
@@ -4893,7 +4889,7 @@
 
   @override
   bool visitMixinDeclaration(MixinDeclaration node) {
-    MixinDeclaration toNode = this._toNode as MixinDeclaration;
+    MixinDeclaration toNode = _toNode as MixinDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4909,7 +4905,7 @@
 
   @override
   bool visitNamedExpression(NamedExpression node) {
-    NamedExpression toNode = this._toNode as NamedExpression;
+    NamedExpression toNode = _toNode as NamedExpression;
     if (_and(_isEqualNodes(node.name, toNode.name),
         _isEqualNodes(node.expression, toNode.expression))) {
       toNode.staticType = node.staticType;
@@ -4920,14 +4916,14 @@
 
   @override
   bool visitNativeClause(NativeClause node) {
-    NativeClause toNode = this._toNode as NativeClause;
+    NativeClause toNode = _toNode as NativeClause;
     return _and(_isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
         _isEqualNodes(node.name, toNode.name));
   }
 
   @override
   bool visitNativeFunctionBody(NativeFunctionBody node) {
-    NativeFunctionBody toNode = this._toNode as NativeFunctionBody;
+    NativeFunctionBody toNode = _toNode as NativeFunctionBody;
     return _and(
         _isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
         _isEqualNodes(node.stringLiteral, toNode.stringLiteral),
@@ -4936,7 +4932,7 @@
 
   @override
   bool visitNullLiteral(NullLiteral node) {
-    NullLiteral toNode = this._toNode as NullLiteral;
+    NullLiteral toNode = _toNode as NullLiteral;
     if (_isEqualTokens(node.literal, toNode.literal)) {
       toNode.staticType = node.staticType;
       return true;
@@ -4946,7 +4942,7 @@
 
   @override
   bool visitOnClause(OnClause node) {
-    OnClause toNode = this._toNode as OnClause;
+    OnClause toNode = _toNode as OnClause;
     return _and(
         _isEqualTokens(node.onKeyword, toNode.onKeyword),
         _isEqualNodeLists(
@@ -4955,7 +4951,7 @@
 
   @override
   bool visitParenthesizedExpression(ParenthesizedExpression node) {
-    ParenthesizedExpression toNode = this._toNode as ParenthesizedExpression;
+    ParenthesizedExpression toNode = _toNode as ParenthesizedExpression;
     if (_and(
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodes(node.expression, toNode.expression),
@@ -4968,7 +4964,7 @@
 
   @override
   bool visitPartDirective(PartDirective node) {
-    PartDirective toNode = this._toNode as PartDirective;
+    PartDirective toNode = _toNode as PartDirective;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4983,7 +4979,7 @@
 
   @override
   bool visitPartOfDirective(PartOfDirective node) {
-    PartOfDirective toNode = this._toNode as PartOfDirective;
+    PartOfDirective toNode = _toNode as PartOfDirective;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -4999,7 +4995,7 @@
 
   @override
   bool visitPostfixExpression(PostfixExpression node) {
-    PostfixExpression toNode = this._toNode as PostfixExpression;
+    PostfixExpression toNode = _toNode as PostfixExpression;
     if (_and(_isEqualNodes(node.operand, toNode.operand),
         _isEqualTokens(node.operator, toNode.operator))) {
       toNode.staticElement = node.staticElement;
@@ -5011,7 +5007,7 @@
 
   @override
   bool visitPrefixedIdentifier(PrefixedIdentifier node) {
-    PrefixedIdentifier toNode = this._toNode as PrefixedIdentifier;
+    PrefixedIdentifier toNode = _toNode as PrefixedIdentifier;
     if (_and(
         _isEqualNodes(node.prefix, toNode.prefix),
         _isEqualTokens(node.period, toNode.period),
@@ -5024,7 +5020,7 @@
 
   @override
   bool visitPrefixExpression(PrefixExpression node) {
-    PrefixExpression toNode = this._toNode as PrefixExpression;
+    PrefixExpression toNode = _toNode as PrefixExpression;
     if (_and(_isEqualTokens(node.operator, toNode.operator),
         _isEqualNodes(node.operand, toNode.operand))) {
       toNode.staticElement = node.staticElement;
@@ -5036,7 +5032,7 @@
 
   @override
   bool visitPropertyAccess(PropertyAccess node) {
-    PropertyAccess toNode = this._toNode as PropertyAccess;
+    PropertyAccess toNode = _toNode as PropertyAccess;
     if (_and(
         _isEqualNodes(node.target, toNode.target),
         _isEqualTokens(node.operator, toNode.operator),
@@ -5051,7 +5047,7 @@
   bool visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node) {
     RedirectingConstructorInvocation toNode =
-        this._toNode as RedirectingConstructorInvocation;
+        _toNode as RedirectingConstructorInvocation;
     if (_and(
         _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
         _isEqualTokens(node.period, toNode.period),
@@ -5065,7 +5061,7 @@
 
   @override
   bool visitRethrowExpression(RethrowExpression node) {
-    RethrowExpression toNode = this._toNode as RethrowExpression;
+    RethrowExpression toNode = _toNode as RethrowExpression;
     if (_isEqualTokens(node.rethrowKeyword, toNode.rethrowKeyword)) {
       toNode.staticType = node.staticType;
       return true;
@@ -5075,7 +5071,7 @@
 
   @override
   bool visitReturnStatement(ReturnStatement node) {
-    ReturnStatement toNode = this._toNode as ReturnStatement;
+    ReturnStatement toNode = _toNode as ReturnStatement;
     return _and(
         _isEqualTokens(node.returnKeyword, toNode.returnKeyword),
         _isEqualNodes(node.expression, toNode.expression),
@@ -5084,13 +5080,13 @@
 
   @override
   bool visitScriptTag(ScriptTag node) {
-    ScriptTag toNode = this._toNode as ScriptTag;
+    ScriptTag toNode = _toNode as ScriptTag;
     return _isEqualTokens(node.scriptTag, toNode.scriptTag);
   }
 
   @override
   bool visitSetOrMapLiteral(SetOrMapLiteral node) {
-    SetOrMapLiteral toNode = this._toNode as SetOrMapLiteral;
+    SetOrMapLiteral toNode = _toNode as SetOrMapLiteral;
     if (_and(
         _isEqualTokens(node.constKeyword, toNode.constKeyword),
         _isEqualNodes(node.typeArguments, toNode.typeArguments),
@@ -5105,14 +5101,14 @@
 
   @override
   bool visitShowCombinator(ShowCombinator node) {
-    ShowCombinator toNode = this._toNode as ShowCombinator;
+    ShowCombinator toNode = _toNode as ShowCombinator;
     return _and(_isEqualTokens(node.keyword, toNode.keyword),
         _isEqualNodeLists(node.shownNames, toNode.shownNames));
   }
 
   @override
   bool visitSimpleFormalParameter(SimpleFormalParameter node) {
-    SimpleFormalParameter toNode = this._toNode as SimpleFormalParameter;
+    SimpleFormalParameter toNode = _toNode as SimpleFormalParameter;
     if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -5128,7 +5124,7 @@
 
   @override
   bool visitSimpleIdentifier(SimpleIdentifier node) {
-    SimpleIdentifier toNode = this._toNode as SimpleIdentifier;
+    SimpleIdentifier toNode = _toNode as SimpleIdentifier;
     if (_isEqualTokens(node.token, toNode.token)) {
       toNode.staticElement = node.staticElement;
       toNode.staticType = node.staticType;
@@ -5142,7 +5138,7 @@
 
   @override
   bool visitSimpleStringLiteral(SimpleStringLiteral node) {
-    SimpleStringLiteral toNode = this._toNode as SimpleStringLiteral;
+    SimpleStringLiteral toNode = _toNode as SimpleStringLiteral;
     if (_and(_isEqualTokens(node.literal, toNode.literal),
         node.value == toNode.value)) {
       toNode.staticType = node.staticType;
@@ -5153,14 +5149,14 @@
 
   @override
   bool visitSpreadElement(SpreadElement node) {
-    SpreadElement toNode = this._toNode as SpreadElement;
+    SpreadElement toNode = _toNode as SpreadElement;
     return _and(_isEqualTokens(node.spreadOperator, toNode.spreadOperator),
         _isEqualNodes(node.expression, toNode.expression));
   }
 
   @override
   bool visitStringInterpolation(StringInterpolation node) {
-    StringInterpolation toNode = this._toNode as StringInterpolation;
+    StringInterpolation toNode = _toNode as StringInterpolation;
     if (_isEqualNodeLists(node.elements, toNode.elements)) {
       toNode.staticType = node.staticType;
       return true;
@@ -5170,8 +5166,7 @@
 
   @override
   bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    SuperConstructorInvocation toNode =
-        this._toNode as SuperConstructorInvocation;
+    SuperConstructorInvocation toNode = _toNode as SuperConstructorInvocation;
     if (_and(
         _isEqualTokens(node.superKeyword, toNode.superKeyword),
         _isEqualTokens(node.period, toNode.period),
@@ -5185,7 +5180,7 @@
 
   @override
   bool visitSuperExpression(SuperExpression node) {
-    SuperExpression toNode = this._toNode as SuperExpression;
+    SuperExpression toNode = _toNode as SuperExpression;
     if (_isEqualTokens(node.superKeyword, toNode.superKeyword)) {
       toNode.staticType = node.staticType;
       return true;
@@ -5195,7 +5190,7 @@
 
   @override
   bool visitSwitchCase(SwitchCase node) {
-    SwitchCase toNode = this._toNode as SwitchCase;
+    SwitchCase toNode = _toNode as SwitchCase;
     return _and(
         _isEqualNodeLists(node.labels, toNode.labels),
         _isEqualTokens(node.keyword, toNode.keyword),
@@ -5206,7 +5201,7 @@
 
   @override
   bool visitSwitchDefault(SwitchDefault node) {
-    SwitchDefault toNode = this._toNode as SwitchDefault;
+    SwitchDefault toNode = _toNode as SwitchDefault;
     return _and(
         _isEqualNodeLists(node.labels, toNode.labels),
         _isEqualTokens(node.keyword, toNode.keyword),
@@ -5216,7 +5211,7 @@
 
   @override
   bool visitSwitchStatement(SwitchStatement node) {
-    SwitchStatement toNode = this._toNode as SwitchStatement;
+    SwitchStatement toNode = _toNode as SwitchStatement;
     return _and(
         _isEqualTokens(node.switchKeyword, toNode.switchKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -5229,7 +5224,7 @@
 
   @override
   bool visitSymbolLiteral(SymbolLiteral node) {
-    SymbolLiteral toNode = this._toNode as SymbolLiteral;
+    SymbolLiteral toNode = _toNode as SymbolLiteral;
     if (_and(_isEqualTokens(node.poundSign, toNode.poundSign),
         _isEqualTokenLists(node.components, toNode.components))) {
       toNode.staticType = node.staticType;
@@ -5240,7 +5235,7 @@
 
   @override
   bool visitThisExpression(ThisExpression node) {
-    ThisExpression toNode = this._toNode as ThisExpression;
+    ThisExpression toNode = _toNode as ThisExpression;
     if (_isEqualTokens(node.thisKeyword, toNode.thisKeyword)) {
       toNode.staticType = node.staticType;
       return true;
@@ -5250,7 +5245,7 @@
 
   @override
   bool visitThrowExpression(ThrowExpression node) {
-    ThrowExpression toNode = this._toNode as ThrowExpression;
+    ThrowExpression toNode = _toNode as ThrowExpression;
     if (_and(_isEqualTokens(node.throwKeyword, toNode.throwKeyword),
         _isEqualNodes(node.expression, toNode.expression))) {
       toNode.staticType = node.staticType;
@@ -5261,8 +5256,7 @@
 
   @override
   bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    TopLevelVariableDeclaration toNode =
-        this._toNode as TopLevelVariableDeclaration;
+    TopLevelVariableDeclaration toNode = _toNode as TopLevelVariableDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -5272,7 +5266,7 @@
 
   @override
   bool visitTryStatement(TryStatement node) {
-    TryStatement toNode = this._toNode as TryStatement;
+    TryStatement toNode = _toNode as TryStatement;
     return _and(
         _isEqualTokens(node.tryKeyword, toNode.tryKeyword),
         _isEqualNodes(node.body, toNode.body),
@@ -5283,7 +5277,7 @@
 
   @override
   bool visitTypeArgumentList(TypeArgumentList node) {
-    TypeArgumentList toNode = this._toNode as TypeArgumentList;
+    TypeArgumentList toNode = _toNode as TypeArgumentList;
     return _and(
         _isEqualTokens(node.leftBracket, toNode.leftBracket),
         _isEqualNodeLists(node.arguments, toNode.arguments),
@@ -5292,7 +5286,7 @@
 
   @override
   bool visitTypeName(TypeName node) {
-    TypeName toNode = this._toNode as TypeName;
+    TypeName toNode = _toNode as TypeName;
     if (_and(
         _isEqualNodes(node.name, toNode.name),
         _isEqualNodes(node.typeArguments, toNode.typeArguments),
@@ -5305,7 +5299,7 @@
 
   @override
   bool visitTypeParameter(TypeParameter node) {
-    TypeParameter toNode = this._toNode as TypeParameter;
+    TypeParameter toNode = _toNode as TypeParameter;
     // TODO (kallentu) : Clean up TypeParameterImpl casting once variance is
     // added to the interface.
     return _and(
@@ -5320,7 +5314,7 @@
 
   @override
   bool visitTypeParameterList(TypeParameterList node) {
-    TypeParameterList toNode = this._toNode as TypeParameterList;
+    TypeParameterList toNode = _toNode as TypeParameterList;
     return _and(
         _isEqualTokens(node.leftBracket, toNode.leftBracket),
         _isEqualNodeLists(node.typeParameters, toNode.typeParameters),
@@ -5329,7 +5323,7 @@
 
   @override
   bool visitVariableDeclaration(VariableDeclaration node) {
-    VariableDeclaration toNode = this._toNode as VariableDeclaration;
+    VariableDeclaration toNode = _toNode as VariableDeclaration;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -5340,7 +5334,7 @@
 
   @override
   bool visitVariableDeclarationList(VariableDeclarationList node) {
-    VariableDeclarationList toNode = this._toNode as VariableDeclarationList;
+    VariableDeclarationList toNode = _toNode as VariableDeclarationList;
     return _and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
@@ -5352,14 +5346,14 @@
   @override
   bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
     VariableDeclarationStatement toNode =
-        this._toNode as VariableDeclarationStatement;
+        _toNode as VariableDeclarationStatement;
     return _and(_isEqualNodes(node.variables, toNode.variables),
         _isEqualTokens(node.semicolon, toNode.semicolon));
   }
 
   @override
   bool visitWhileStatement(WhileStatement node) {
-    WhileStatement toNode = this._toNode as WhileStatement;
+    WhileStatement toNode = _toNode as WhileStatement;
     return _and(
         _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
@@ -5370,14 +5364,14 @@
 
   @override
   bool visitWithClause(WithClause node) {
-    WithClause toNode = this._toNode as WithClause;
+    WithClause toNode = _toNode as WithClause;
     return _and(_isEqualTokens(node.withKeyword, toNode.withKeyword),
         _isEqualNodeLists(node.mixinTypes, toNode.mixinTypes));
   }
 
   @override
   bool visitYieldStatement(YieldStatement node) {
-    YieldStatement toNode = this._toNode as YieldStatement;
+    YieldStatement toNode = _toNode as YieldStatement;
     return _and(
         _isEqualTokens(node.yieldKeyword, toNode.yieldKeyword),
         _isEqualNodes(node.expression, toNode.expression),
@@ -5443,7 +5437,7 @@
     } else if (toNode == null) {
       return false;
     } else if (fromNode.runtimeType == toNode.runtimeType) {
-      this._toNode = toNode;
+      _toNode = toNode;
       return fromNode.accept(this);
     }
     //
@@ -5452,13 +5446,13 @@
     if (toNode is PrefixedIdentifier) {
       SimpleIdentifier prefix = toNode.prefix;
       if (fromNode.runtimeType == prefix.runtimeType) {
-        this._toNode = prefix;
+        _toNode = prefix;
         return fromNode.accept(this);
       }
     } else if (toNode is PropertyAccess) {
       Expression target = toNode.target;
       if (fromNode.runtimeType == target.runtimeType) {
-        this._toNode = target;
+        _toNode = target;
         return fromNode.accept(this);
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 7db09b6..ffccab6 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -366,14 +366,12 @@
           identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM) ||
           identical(dataErrorCode,
               CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT) ||
-          identical(
-              dataErrorCode,
-              CheckedModeCompileTimeErrorCode
-                  .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) ||
+          identical(dataErrorCode,
+              CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) ||
           identical(dataErrorCode,
               CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH) ||
-          identical(dataErrorCode,
-              CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH)) {
+          identical(
+              dataErrorCode, CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH)) {
         _errorReporter.reportError(data);
       } else if (errorCode != null) {
         _errorReporter.reportError(
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index d844664..9a4651c 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -232,7 +232,7 @@
             //  CompileTimeErrorCode.INVALID_ASSIGNMENT has already been
             //  reported (that is, if the static types are also wrong).
             errorReporter.reportErrorForNode(
-                CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+                CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
                 constantInitializer,
                 [dartObject.type, constant.type]);
           }
@@ -575,8 +575,7 @@
             FieldMember.from(field, constructor.returnType).type;
         if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) {
           errorReporter.reportErrorForNode(
-              CheckedModeCompileTimeErrorCode
-                  .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+              CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
               node,
               [fieldValue.type, field.name, fieldType]);
         }
@@ -678,8 +677,7 @@
             PropertyInducingElement field = getter.variable;
             if (!runtimeTypeMatch(evaluationResult, field.type)) {
               errorReporter.reportErrorForNode(
-                  CheckedModeCompileTimeErrorCode
-                      .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+                  CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
                   node,
                   [evaluationResult.type, fieldName, field.type]);
             }
@@ -976,8 +974,7 @@
     Substitution substitution,
   })  : _lexicalEnvironment = lexicalEnvironment,
         _substitution = substitution {
-    this._dartObjectComputer =
-        DartObjectComputer(_errorReporter, evaluationEngine);
+    _dartObjectComputer = DartObjectComputer(_errorReporter, evaluationEngine);
   }
 
   /// Return the object representing the state of active experiments.
@@ -2227,13 +2224,13 @@
   final DartObjectImpl value;
 
   EvaluationResultImpl(this.value, [List<AnalysisError> errors]) {
-    this._errors = errors ?? <AnalysisError>[];
+    _errors = errors ?? <AnalysisError>[];
   }
 
   List<AnalysisError> get errors => _errors;
 
   bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
-    if (this.value != null) {
+    if (value != null) {
       if (result.value == null) {
         return false;
       }
diff --git a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
index d5b6933..1f8e249 100644
--- a/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
+++ b/pkg/analyzer/lib/src/dart/element/class_hierarchy.dart
@@ -25,8 +25,7 @@
   }
 
   /// Remove hierarchies for classes defined in specified libraries.
-  void removeOfLibraries(Iterable<String> uriStrIterable) {
-    var uriStrSet = uriStrIterable.toSet();
+  void removeOfLibraries(Set<String> uriStrSet) {
     _map.removeWhere((element, _) {
       var uriStr = '${element.librarySource.uri}';
       return uriStrSet.contains(uriStr);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index eea79c5..8cc2292 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -85,7 +85,7 @@
     for (PropertyAccessorElement accessor in accessors) {
       (accessor as PropertyAccessorElementImpl).enclosingElement = this;
     }
-    this._accessors = accessors;
+    _accessors = accessors;
   }
 
   @override
@@ -99,7 +99,7 @@
     for (FieldElement field in fields) {
       (field as FieldElementImpl).enclosingElement = this;
     }
-    this._fields = fields;
+    _fields = fields;
   }
 
   @override
@@ -597,7 +597,7 @@
     for (ConstructorElement constructor in constructors) {
       (constructor as ConstructorElementImpl).enclosingElement = this;
     }
-    this._constructors = constructors;
+    _constructors = constructors;
   }
 
   @override
@@ -931,7 +931,7 @@
     for (TypeParameterElement typeParameter in typeParameters) {
       (typeParameter as TypeParameterElementImpl).enclosingElement = this;
     }
-    this._typeParameterElements = typeParameters;
+    _typeParameterElements = typeParameters;
   }
 
   @override
@@ -1312,7 +1312,7 @@
     for (PropertyAccessorElement accessor in accessors) {
       (accessor as PropertyAccessorElementImpl).enclosingElement = this;
     }
-    this._accessors = accessors;
+    _accessors = accessors;
   }
 
   @override
@@ -1365,7 +1365,7 @@
     for (ClassElement enumDeclaration in enums) {
       (enumDeclaration as EnumElementImpl).enclosingElement = this;
     }
-    this._enums = enums;
+    _enums = enums;
   }
 
   @override
@@ -1402,7 +1402,7 @@
     for (ExtensionElement extension in extensions) {
       (extension as ExtensionElementImpl).enclosingElement = this;
     }
-    this._extensions = extensions;
+    _extensions = extensions;
   }
 
   @override
@@ -1433,7 +1433,7 @@
     for (FunctionElement function in functions) {
       (function as FunctionElementImpl).enclosingElement = this;
     }
-    this._functions = functions;
+    _functions = functions;
   }
 
   @override
@@ -1510,7 +1510,7 @@
     for (MixinElementImpl type in mixins) {
       type.enclosingElement = this;
     }
-    this._mixins = mixins;
+    _mixins = mixins;
   }
 
   @override
@@ -1530,7 +1530,7 @@
     for (TopLevelVariableElement field in variables) {
       (field as TopLevelVariableElementImpl).enclosingElement = this;
     }
-    this._variables = variables;
+    _variables = variables;
   }
 
   /// Set the function type aliases contained in this compilation unit to the
@@ -1539,7 +1539,7 @@
     for (FunctionTypeAliasElement typeAlias in typeAliases) {
       (typeAlias as ElementImpl).enclosingElement = this;
     }
-    this._typeAliases = typeAliases;
+    _typeAliases = typeAliases;
   }
 
   @override
@@ -1588,7 +1588,7 @@
         type.enclosingElement = this;
       }
     }
-    this._types = types;
+    _types = types;
   }
 
   @override
@@ -2644,8 +2644,8 @@
   /// [_nameOffset].
   ElementImpl(String name, this._nameOffset, {this.reference})
       : linkedNode = null {
-    this._name = StringUtilities.intern(name);
-    this.reference?.element = this;
+    _name = StringUtilities.intern(name);
+    reference?.element = this;
   }
 
   /// Initialize from linked node.
@@ -2970,7 +2970,7 @@
 
   /// Changes the name of this element.
   set name(String name) {
-    this._name = name;
+    _name = name;
   }
 
   @override
@@ -3204,17 +3204,17 @@
       components.insert(0, (ancestor as ElementImpl).identifier);
       ancestor = ancestor.enclosingElement;
     }
-    this._components = components;
+    _components = components;
   }
 
   /// Initialize a newly created location from the given [encoding].
   ElementLocationImpl.con2(String encoding) {
-    this._components = _decode(encoding);
+    _components = _decode(encoding);
   }
 
   /// Initialize a newly created location from the given [components].
   ElementLocationImpl.con3(List<String> components) {
-    this._components = components;
+    _components = components;
   }
 
   @override
@@ -3531,7 +3531,7 @@
     }
 
     // Build fields for all enum constants.
-    var containerRef = this.reference.getChild('@constant');
+    var containerRef = reference.getChild('@constant');
     var constants = linkedContext.getEnumConstants(linkedNode);
     for (var i = 0; i < constants.length; ++i) {
       var constant = constants[i];
@@ -3700,7 +3700,7 @@
     for (ParameterElement parameter in parameters) {
       (parameter as ParameterElementImpl).enclosingElement = this;
     }
-    this._parameters = parameters;
+    _parameters = parameters;
   }
 
   /// Gets the element's parameters, without going through the indirection of
@@ -3782,7 +3782,7 @@
     for (TypeParameterElement parameter in typeParameters) {
       (parameter as TypeParameterElementImpl).enclosingElement = this;
     }
-    this._typeParameterElements = typeParameters;
+    _typeParameterElements = typeParameters;
   }
 
   @override
@@ -4101,7 +4101,7 @@
     for (TypeParameterElement typeParameter in typeParameters) {
       (typeParameter as TypeParameterElementImpl).enclosingElement = this;
     }
-    this._typeParameterElements = typeParameters;
+    _typeParameterElements = typeParameters;
   }
 
   @override
@@ -4238,13 +4238,13 @@
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
 
-      this.getter = PropertyAccessorElementImpl_ImplicitGetter(
+      getter = PropertyAccessorElementImpl_ImplicitGetter(
         this,
         reference: enclosingRef.getChild('@getter').getChild(name),
       );
 
       if (_hasSetter) {
-        this.setter = PropertyAccessorElementImpl_ImplicitSetter(
+        setter = PropertyAccessorElementImpl_ImplicitSetter(
           this,
           reference: enclosingRef.getChild('@setter').getChild(name),
         );
@@ -4403,7 +4403,7 @@
   @override
   String get identifier {
     String identifier = super.identifier;
-    Element enclosing = this.enclosingElement;
+    Element enclosing = enclosingElement;
     if (enclosing is ExecutableElement) {
       identifier += "@$nameOffset";
     }
@@ -4515,7 +4515,7 @@
     for (ParameterElement parameter in parameters) {
       (parameter as ParameterElementImpl).enclosingElement = this;
     }
-    this._parameters = parameters;
+    _parameters = parameters;
   }
 
   @override
@@ -4580,7 +4580,7 @@
     for (TypeParameterElement parameter in typeParameters) {
       (parameter as TypeParameterElementImpl).enclosingElement = this;
     }
-    this._typeParameterElements = typeParameters;
+    _typeParameterElements = typeParameters;
   }
 
   @override
@@ -4786,7 +4786,7 @@
     for (TypeParameterElement typeParameter in typeParameters) {
       (typeParameter as TypeParameterElementImpl).enclosingElement = this;
     }
-    this._typeParameterElements = typeParameters;
+    _typeParameterElements = typeParameters;
   }
 
   @override
@@ -5268,7 +5268,7 @@
   set definingCompilationUnit(CompilationUnitElement unit) {
     assert((unit as CompilationUnitElementImpl).librarySource == unit.source);
     (unit as CompilationUnitElementImpl).enclosingElement = this;
-    this._definingCompilationUnit = unit;
+    _definingCompilationUnit = unit;
   }
 
   @override
@@ -5349,7 +5349,7 @@
     for (ExportElement exportElement in exports) {
       (exportElement as ExportElementImpl).enclosingElement = this;
     }
-    this._exports = exports;
+    _exports = exports;
   }
 
   @override
@@ -5441,8 +5441,8 @@
         prefix.enclosingElement = this;
       }
     }
-    this._imports = imports;
-    this._prefixes = null;
+    _imports = imports;
+    _prefixes = null;
   }
 
   @override
@@ -5565,7 +5565,7 @@
           source);
       (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
     }
-    this._parts = parts;
+    _parts = parts;
   }
 
   @override
@@ -6561,7 +6561,7 @@
 
   /// Set Dart code of the default value.
   set defaultValueCode(String defaultValueCode) {
-    this._defaultValueCode = StringUtilities.intern(defaultValueCode);
+    _defaultValueCode = StringUtilities.intern(defaultValueCode);
   }
 
   @override
@@ -6719,7 +6719,7 @@
     for (ParameterElement parameter in parameters) {
       (parameter as ParameterElementImpl).enclosingElement = this;
     }
-    this._parameters = parameters;
+    _parameters = parameters;
   }
 
   @override
@@ -6764,7 +6764,7 @@
     for (TypeParameterElement parameter in typeParameters) {
       (parameter as TypeParameterElementImpl).enclosingElement = this;
     }
-    this._typeParameters = typeParameters;
+    _typeParameters = typeParameters;
   }
 
   @override
@@ -7422,13 +7422,13 @@
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
 
-      this.getter = PropertyAccessorElementImpl_ImplicitGetter(
+      getter = PropertyAccessorElementImpl_ImplicitGetter(
         this,
         reference: enclosingRef.getChild('@getter').getChild(name),
       );
 
       if (_hasSetter) {
-        this.setter = PropertyAccessorElementImpl_ImplicitSetter(
+        setter = PropertyAccessorElementImpl_ImplicitSetter(
           this,
           reference: enclosingRef.getChild('@setter').getChild(name),
         );
@@ -7568,7 +7568,7 @@
   @override
   String get name {
     if (linkedNode != null) {
-      TypeParameter node = this.linkedNode;
+      TypeParameter node = linkedNode;
       return node.name.name;
     }
     return super.name;
@@ -7811,7 +7811,7 @@
     if (function != null) {
       (function as FunctionElementImpl).enclosingElement = this;
     }
-    this._initializer = function;
+    _initializer = function;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart
index 05bab210..ff2a475 100644
--- a/pkg/analyzer/lib/src/dart/element/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/element/extensions.dart
@@ -14,7 +14,7 @@
       name,
       type ?? this.type,
       // ignore: deprecated_member_use_from_same_package
-      kind ?? this.parameterKind,
+      kind ?? parameterKind,
     )..isExplicitlyCovariant = isCovariant;
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index 29ca0cc..52fab94 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -165,7 +165,7 @@
     var knownTypes = <TypeParameterElement, DartType>{};
     for (int i = 0; i < typeFormals.length; i++) {
       TypeParameterElement typeParam = typeFormals[i];
-      var constraints = this._constraints[typeParam];
+      var constraints = _constraints[typeParam];
       var typeParamBound = typeParam.bound != null
           ? Substitution.fromPairs(typeFormals, inferredTypes)
               .substituteType(typeParam.bound)
@@ -224,8 +224,13 @@
         // by [infer], with [typeParam] filled in as its bounds. This is
         // considered a failure of inference, under the "strict-inference"
         // mode.
-        if (errorNode is ConstructorName) {
-          String constructorName = '${errorNode.type}.${errorNode.name}';
+        if (errorNode is ConstructorName &&
+            !(errorNode.type.type as InterfaceType)
+                .element
+                .hasOptionalTypeArgs) {
+          String constructorName = errorNode.name == null
+              ? errorNode.type.name.name
+              : '${errorNode.type}.${errorNode.name}';
           errorReporter?.reportErrorForNode(
               HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION,
               errorNode,
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index bb1f519..9189fad 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -307,6 +307,14 @@
     return interface._overridden[name];
   }
 
+  /// Remove interfaces for classes defined in specified libraries.
+  void removeOfLibraries(Set<String> uriStrSet) {
+    _interfaces.removeWhere((element, _) {
+      var uriStr = '${element.librarySource.uri}';
+      return uriStrSet.contains(uriStr);
+    });
+  }
+
   void _addCandidates({
     @required Map<Name, List<ExecutableElement>> namedCandidates,
     @required Substitution substitution,
diff --git a/pkg/analyzer/lib/src/dart/element/replace_top_bottom_visitor.dart b/pkg/analyzer/lib/src/dart/element/replace_top_bottom_visitor.dart
new file mode 100644
index 0000000..7e5e457
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/replace_top_bottom_visitor.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, 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/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/replacement_visitor.dart';
+import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:meta/meta.dart';
+
+/// Replace every "top" type in a covariant position with [_bottomType].
+/// Replace every "bottom" type in a contravariant position with [_topType].
+class ReplaceTopBottomVisitor extends ReplacementVisitor {
+  final DartType _topType;
+  final DartType _bottomType;
+  final TypeSystemImpl _typeSystem;
+
+  bool _isCovariant;
+
+  ReplaceTopBottomVisitor._(
+    this._typeSystem,
+    this._topType,
+    this._bottomType,
+    this._isCovariant,
+  );
+
+  @override
+  void changeVariance() {
+    _isCovariant = !_isCovariant;
+  }
+
+  @override
+  DartType visitDynamicType(DynamicType type) {
+    return _isCovariant ? _bottomType : null;
+  }
+
+  @override
+  DartType visitInterfaceType(InterfaceType type) {
+    if (_isCovariant) {
+      if (_typeSystem.isTop(type)) {
+        return _bottomType;
+      }
+    } else {
+      if (!_typeSystem.isNonNullableByDefault && type.isDartCoreNull) {
+        return _topType;
+      }
+    }
+
+    return super.visitInterfaceType(type);
+  }
+
+  @override
+  DartType visitNeverType(NeverType type) {
+    return _isCovariant ? null : _topType;
+  }
+
+  @override
+  DartType visitVoidType(VoidType type) {
+    return _isCovariant ? _bottomType : null;
+  }
+
+  /// Runs an instance of the visitor on the given [type] and returns the
+  /// resulting type.  If the type contains no instances of Top or Bottom, the
+  /// original type object is returned to avoid unnecessary allocation.
+  static DartType run({
+    @required DartType topType,
+    @required DartType bottomType,
+    @required TypeSystemImpl typeSystem,
+    @required DartType type,
+  }) {
+    var visitor = ReplaceTopBottomVisitor._(
+      typeSystem,
+      topType,
+      bottomType,
+      true,
+    );
+    var result = type.accept(visitor);
+    assert(visitor._isCovariant == true);
+    return result ?? type;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/runtime_type_equality.dart b/pkg/analyzer/lib/src/dart/element/runtime_type_equality.dart
index 3f54b89..07be5ad 100644
--- a/pkg/analyzer/lib/src/dart/element/runtime_type_equality.dart
+++ b/pkg/analyzer/lib/src/dart/element/runtime_type_equality.dart
@@ -5,11 +5,11 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_visitor.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/dart/element/type_visitor.dart';
 
 class RuntimeTypeEqualityHelper {
   final TypeSystemImpl _typeSystem;
@@ -23,24 +23,16 @@
   bool equal(DartType T1, DartType T2) {
     var N1 = _typeSystem.normalize(T1);
     var N2 = _typeSystem.normalize(T2);
-    return const RuntimeTypeEqualityVisitor().visit(N1, N2);
+    return N1.acceptWithArgument(const RuntimeTypeEqualityVisitor(), N2);
   }
 }
 
-class RuntimeTypeEqualityVisitor extends DartTypeVisitor1<bool, DartType> {
+class RuntimeTypeEqualityVisitor
+    extends TypeVisitorWithArgument<bool, DartType> {
   const RuntimeTypeEqualityVisitor();
 
   @override
-  bool defaultDartType(DartType T1, DartType T2) {
-    throw UnimplementedError('(${T1.runtimeType}) $T1');
-  }
-
-  bool visit(DartType T1, DartType T2) {
-    return DartTypeVisitor1.visit(T1, this, T2);
-  }
-
-  @override
-  bool visitDynamicType(DynamicTypeImpl T1, DartType T2) {
+  bool visitDynamicType(DynamicType T1, DartType T2) {
     return identical(T1, T2);
   }
 
@@ -55,7 +47,7 @@
       bool equal(DartType T1, DartType T2) {
         T1 = typeParameters.T1_substitution.substituteType(T1);
         T2 = typeParameters.T2_substitution.substituteType(T2);
-        return visit(T1, T2);
+        return T1.acceptWithArgument(this, T2);
       }
 
       if (!equal(T1.returnType, T2.returnType)) {
@@ -104,7 +96,7 @@
         for (var i = 0; i < T1_typeArguments.length; i++) {
           var T1_typeArgument = T1_typeArguments[i];
           var T2_typeArgument = T2_typeArguments[i];
-          if (!visit(T1_typeArgument, T2_typeArgument)) {
+          if (!T1_typeArgument.acceptWithArgument(this, T2_typeArgument)) {
             return false;
           }
         }
@@ -115,7 +107,7 @@
   }
 
   @override
-  bool visitNeverType(NeverTypeImpl T1, DartType T2) {
+  bool visitNeverType(NeverType T1, DartType T2) {
     // Note, that all types are normalized before this visitor.
     // So, `Never?` never happens, it is already `Null`.
     assert(T1.nullabilitySuffix != NullabilitySuffix.question);
@@ -181,7 +173,7 @@
       } else if (T1_bound != null && T2_bound != null) {
         T1_bound = T1_substitution.substituteType(T1_bound);
         T2_bound = T2_substitution.substituteType(T2_bound);
-        if (!visit(T1_bound, T2_bound)) {
+        if (!T1_bound.acceptWithArgument(this, T2_bound)) {
           return null;
         }
       } else {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 4eea090..84de8e0 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_visitor.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/display_string_builder.dart';
@@ -75,18 +74,16 @@
   }
 
   @override
-  void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeDynamicType();
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    return visitor.visitDynamicType(this, argument);
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    if (isCovariant) {
-      return NeverTypeImpl.instance;
-    } else {
-      return this;
-    }
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeDynamicType();
   }
 
   @override
@@ -280,6 +277,14 @@
   }
 
   @override
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    return visitor.visitFunctionType(this, argument);
+  }
+
+  @override
   void appendTo(ElementDisplayStringBuilder builder) {
     builder.writeFunctionType(this);
   }
@@ -311,33 +316,6 @@
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    var returnType = (this.returnType as TypeImpl)
-        .replaceTopAndBottom(typeProvider, isCovariant: isCovariant);
-    ParameterElement transformParameter(ParameterElement p) {
-      TypeImpl type = p.type;
-      var newType = type.replaceTopAndBottom(
-        typeProvider,
-        isCovariant: !isCovariant,
-      );
-      return p.copyWith(type: newType);
-    }
-
-    var parameters = _transformOrShare(this.parameters, transformParameter);
-    if (identical(returnType, this.returnType) &&
-        identical(parameters, this.parameters)) {
-      return this;
-    }
-    return FunctionTypeImpl(
-      typeFormals: typeFormals,
-      parameters: parameters,
-      returnType: returnType,
-      nullabilitySuffix: nullabilitySuffix,
-    );
-  }
-
-  @override
   @deprecated
   FunctionType substitute2(
       List<DartType> argumentTypes, List<DartType> parameterTypes) {
@@ -898,6 +876,14 @@
   }
 
   @override
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    return visitor.visitInterfaceType(this, argument);
+  }
+
+  @override
   void appendTo(ElementDisplayStringBuilder builder) {
     builder.writeInterfaceType(this);
   }
@@ -1372,34 +1358,6 @@
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    // First check if this is actually an instance of Bottom
-    if (this.isDartCoreNull) {
-      if (isCovariant) {
-        return this;
-      } else {
-        return typeProvider.objectType;
-      }
-    }
-
-    // Otherwise, recurse over type arguments.
-    var typeArguments = _transformOrShare(
-        this.typeArguments,
-        (t) => (t as TypeImpl)
-            .replaceTopAndBottom(typeProvider, isCovariant: isCovariant));
-    if (identical(typeArguments, this.typeArguments)) {
-      return this;
-    } else {
-      return InterfaceTypeImpl(
-        element: element,
-        typeArguments: typeArguments,
-        nullabilitySuffix: nullabilitySuffix,
-      );
-    }
-  }
-
-  @override
   @deprecated
   InterfaceTypeImpl substitute2(
       List<DartType> argumentTypes, List<DartType> parameterTypes) {
@@ -1695,26 +1653,16 @@
   }
 
   @override
-  void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeNeverType(this);
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    return visitor.visitNeverType(this, argument);
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    if (isCovariant) {
-      return this;
-    } else {
-      // In theory this should never happen, since we only need to do this
-      // replacement when checking super-boundedness of explicitly-specified
-      // types, or types produced by mixin inference or instantiate-to-bounds,
-      // and bottom can't occur in any of those cases.
-      assert(false,
-          'Attempted to check super-boundedness of a type including "bottom"');
-      // But just in case it does, return `dynamic` since that's similar to what
-      // we do with Null.
-      return typeProvider.objectType;
-    }
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeNeverType(this);
   }
 
   @override
@@ -1839,14 +1787,6 @@
     return builder.toString();
   }
 
-  /// Replaces all covariant occurrences of `dynamic`, `Object`, and `void` with
-  /// `Null` and all contravariant occurrences of `Null` with `Object`.
-  ///
-  /// The boolean `isCovariant` indicates whether this type is in covariant or
-  /// contravariant position.
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true});
-
   @override
   DartType resolveToBound(DartType objectType) => this;
 
@@ -1994,6 +1934,14 @@
   }
 
   @override
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    return visitor.visitTypeParameterType(this, argument);
+  }
+
+  @override
   void appendTo(ElementDisplayStringBuilder builder) {
     builder.writeTypeParameterType(this);
   }
@@ -2004,12 +1952,6 @@
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    return this;
-  }
-
-  @override
   DartType resolveToBound(DartType objectType) {
     if (promotedBound != null) {
       return promotedBound;
@@ -2140,18 +2082,16 @@
   }
 
   @override
-  void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeVoidType();
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    return visitor.visitVoidType(this, argument);
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    if (isCovariant) {
-      return typeProvider.nullType;
-    } else {
-      return this;
-    }
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeVoidType();
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 9ba3091..6d5bf1a 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -404,7 +404,7 @@
     // any uses, but does not tell if the resulting function type is distinct.
     // Our own use counter will get incremented if something from our
     // environment has been used inside the function.
-    int before = this.useCounter;
+    int before = useCounter;
 
     var inner = this;
     var typeFormals = type.typeFormals;
@@ -426,7 +426,7 @@
     var returnType = type.returnType.accept(inner);
     var typeArguments = _mapList(type.typeArguments);
 
-    if (this.useCounter == before) return type;
+    if (useCounter == before) return type;
 
     return FunctionTypeImpl(
       typeFormals: typeFormals,
@@ -451,7 +451,7 @@
     // any uses, but does not tell if the resulting function type is distinct.
     // Our own use counter will get incremented if something from our
     // environment has been used inside the function.
-    int before = this.useCounter;
+    int before = useCounter;
 
     var inner = this;
     var typeFormals = type.typeFormals;
@@ -472,7 +472,7 @@
 
     var returnType = type.returnType.accept(inner);
 
-    if (this.useCounter == before) return type;
+    if (useCounter == before) return type;
 
     return FunctionTypeBuilder(
       typeFormals,
diff --git a/pkg/analyzer/lib/src/dart/element/type_schema.dart b/pkg/analyzer/lib/src/dart/element/type_schema.dart
index a26acd1..1f4b6c4 100644
--- a/pkg/analyzer/lib/src/dart/element/type_schema.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_schema.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/dart/ast/token.dart' show Keyword;
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_visitor.dart';
 import 'package:analyzer/src/dart/element/display_string_builder.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -49,25 +48,21 @@
   }
 
   @override
-  void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeUnknownInferredType();
+  R acceptWithArgument<R, A>(
+    TypeVisitorWithArgument<R, A> visitor,
+    A argument,
+  ) {
+    if (visitor is InferenceTypeVisitor1<R, A>) {
+      var visitor2 = visitor as InferenceTypeVisitor1<R, A>;
+      return visitor2.visitUnknownInferredType(this, argument);
+    } else {
+      throw StateError('Should not happen outside inference.');
+    }
   }
 
   @override
-  DartType replaceTopAndBottom(TypeProvider typeProvider,
-      {bool isCovariant = true}) {
-    // In theory this should never happen, since we only need to do this
-    // replacement when checking super-boundedness of explicitly-specified
-    // types, or types produced by mixin inference or instantiate-to-bounds, and
-    // the unknown type can't occur in any of those cases.
-    assert(
-        false, 'Attempted to check super-boundedness of a type including "_"');
-    // But just in case it does, behave similar to `dynamic`.
-    if (isCovariant) {
-      return typeProvider.nullType;
-    } else {
-      return this;
-    }
+  void appendTo(ElementDisplayStringBuilder builder) {
+    builder.writeUnknownInferredType();
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index 01a252f..f01860f 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/dart/element/least_upper_bound.dart';
 import 'package:analyzer/src/dart/element/normalize.dart';
 import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
+import 'package:analyzer/src/dart/element/replace_top_bottom_visitor.dart';
 import 'package:analyzer/src/dart/element/runtime_type_equality.dart';
 import 'package:analyzer/src/dart/element/subtype.dart';
 import 'package:analyzer/src/dart/element/top_merge.dart';
@@ -1430,6 +1431,27 @@
     return currentType;
   }
 
+  /// Replaces all covariant occurrences of `dynamic`, `void`, and `Object` or
+  /// `Object?` with `Null` or `Never` and all contravariant occurrences of
+  /// `Null` or `Never` with `Object` or `Object?`.
+  DartType replaceTopAndBottom(DartType dartType) {
+    if (isNonNullableByDefault) {
+      return ReplaceTopBottomVisitor.run(
+        topType: objectQuestion,
+        bottomType: NeverTypeImpl.instance,
+        typeSystem: this,
+        type: dartType,
+      );
+    } else {
+      return ReplaceTopBottomVisitor.run(
+        topType: DynamicTypeImpl.instance,
+        bottomType: typeProvider.nullType,
+        typeSystem: this,
+        type: dartType,
+      );
+    }
+  }
+
   /// Return `true` if runtime types [T1] and [T2] are equal.
   ///
   /// nnbd/feature-specification.md#runtime-type-equality-operator
diff --git a/pkg/analyzer/lib/src/dart/element/type_visitor.dart b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
index 78ce59a..a10644a 100644
--- a/pkg/analyzer/lib/src/dart/element/type_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
@@ -4,84 +4,10 @@
 
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_visitor.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 
-class DartTypeVisitor1<R, T> {
-  const DartTypeVisitor1();
-
-  R defaultDartType(DartType type, T arg) => null;
-
-  R visitDynamicType(DynamicTypeImpl type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitFunctionType(FunctionType type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitFunctionTypeBuilder(FunctionTypeBuilder type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitInterfaceType(InterfaceType type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitNamedTypeBuilder(NamedTypeBuilder type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitNeverType(NeverTypeImpl type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitTypeParameterType(TypeParameterType type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitUnknownInferredType(UnknownInferredType type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  R visitVoidType(VoidType type, T arg) {
-    return defaultDartType(type, arg);
-  }
-
-  static R visit<R, T>(DartType type, DartTypeVisitor1<R, T> visitor, T arg) {
-    if (type is NeverTypeImpl) {
-      return visitor.visitNeverType(type, arg);
-    }
-    if (type is DynamicTypeImpl) {
-      return visitor.visitDynamicType(type, arg);
-    }
-    if (type is FunctionType) {
-      return visitor.visitFunctionType(type, arg);
-    }
-    if (type is FunctionTypeBuilder) {
-      return visitor.visitFunctionTypeBuilder(type, arg);
-    }
-    if (type is InterfaceType) {
-      return visitor.visitInterfaceType(type, arg);
-    }
-    if (type is NamedTypeBuilder) {
-      return visitor.visitNamedTypeBuilder(type, arg);
-    }
-    if (type is TypeParameterType) {
-      return visitor.visitTypeParameterType(type, arg);
-    }
-    if (type is UnknownInferredType) {
-      return visitor.visitUnknownInferredType(type, arg);
-    }
-    if (type is VoidType) {
-      return visitor.visitVoidType(type, arg);
-    }
-    throw UnimplementedError('(${type.runtimeType}) $type');
-  }
-}
-
 /// Visitors that implement this interface can be used to visit partially
 /// inferred types, during type inference.
 abstract class InferenceTypeVisitor<R> {
@@ -89,6 +15,12 @@
 }
 
 /// Visitors that implement this interface can be used to visit partially
+/// inferred types, during type inference.
+abstract class InferenceTypeVisitor1<R, A> {
+  R visitUnknownInferredType(UnknownInferredType type, A argument);
+}
+
+/// Visitors that implement this interface can be used to visit partially
 /// built types, during linking element model.
 abstract class LinkingTypeVisitor<R> {
   R visitFunctionTypeBuilder(FunctionTypeBuilder type);
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index ddd22b4..e187c17 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -537,7 +537,7 @@
    */
   static const HintCode INFERENCE_FAILURE_ON_INSTANCE_CREATION = HintCode(
       'INFERENCE_FAILURE_ON_INSTANCE_CREATION',
-      "The type argument(s) of '{0}' can't be inferred.",
+      "The type argument(s) of the constructor '{0}' can't be inferred.",
       correction: "Use explicit type argument(s) for '{0}'.");
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index 2d3ee76..3a1a6253 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -115,7 +115,7 @@
     this.sourceFactory,
     this.resourceProvider, {
     Workspace workspace,
-  }) : this._workspace = workspace;
+  }) : _workspace = workspace;
 
   @override
   AnalysisOptionsImpl get analysisOptions {
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 080fae0..eeb514b 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -103,12 +103,12 @@
     @required Workspace workspace,
     CiderByteStore byteStore,
     Duration libraryContextResetTimeout = const Duration(seconds: 60),
-  })  : this.logger = logger,
-        this.sourceFactory = sourceFactory,
-        this.resourceProvider = resourceProvider,
-        this.getFileDigest = getFileDigest,
-        this.prefetchFiles = prefetchFiles,
-        this.workspace = workspace {
+  })  : logger = logger,
+        sourceFactory = sourceFactory,
+        resourceProvider = resourceProvider,
+        getFileDigest = getFileDigest,
+        prefetchFiles = prefetchFiles,
+        workspace = workspace {
     byteStore ??= CiderMemoryByteStore();
     this.byteStore = byteStore;
     _libraryContextReset = _LibraryContextReset(
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index b4bb472..c8b7f64 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -65,8 +65,7 @@
           var typeArguments = node.typeArguments;
           if (typeArguments != null) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode
-                    .WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+                CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
                 typeArguments,
                 [element.name, constructorElement.name]);
           }
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 3b74a26..2787d4b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -453,14 +453,14 @@
   // TODO(scheglov) check if it might be inlined
   Element lookupIdentifier(Identifier identifier) {
     if (identifier is SimpleIdentifier) {
-      var result = this.lookup2(identifier.name);
+      var result = lookup2(identifier.name);
       return result.getter ?? result.setter;
     } else {
       var prefixedIdentifier = identifier as PrefixedIdentifier;
 
       var prefixIdentifier = prefixedIdentifier.prefix;
       var prefixName = prefixIdentifier.name;
-      var prefixElement = this.lookup2(prefixName).getter;
+      var prefixElement = lookup2(prefixName).getter;
       prefixIdentifier.staticElement = prefixElement;
 
       if (prefixElement is PrefixElement) {
diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
index c2ce2e8..7266b2d 100644
--- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
@@ -102,7 +102,7 @@
   fasta.LanguageVersionToken get languageVersion => _languageVersion;
 
   set preserveComments(bool preserveComments) {
-    this._preserveComments = preserveComments;
+    _preserveComments = preserveComments;
   }
 
   /// Configures the scanner appropriately for the given [featureSet].
@@ -114,8 +114,8 @@
     @required FeatureSet featureSetForOverriding,
     @required FeatureSet featureSet,
   }) {
-    this._featureSetForOverriding = featureSetForOverriding;
-    this._featureSet = featureSet;
+    _featureSetForOverriding = featureSetForOverriding;
+    _featureSet = featureSet;
     enableGtGtGt = featureSet.isEnabled(Feature.triple_shift);
     enableNonNullable = featureSet.isEnabled(Feature.non_nullable);
   }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index f53e655..c929868 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -16,113 +16,6 @@
 // ignore_for_file: slash_for_doc_comments
 
 /**
- * The error codes used for compile time errors caused by constant evaluation
- * that would throw an exception when run in checked mode. The client of the
- * analysis engine is responsible for determining how these errors should be
- * presented to the user (for example, a command-line compiler might elect to
- * treat these errors differently depending whether it is compiling it "checked"
- * mode).
- */
-class CheckedModeCompileTimeErrorCode extends AnalyzerErrorCode {
-  // TODO(paulberry): improve the text of these error messages so that it's
-  // clear to the user that the error is coming from constant evaluation (and
-  // hence the constant needs to be a subtype of the annotated type) as opposed
-  // to static type analysis (which only requires that the two types be
-  // assignable).  Also consider populating the "correction" field for these
-  // errors.
-
-  /**
-   * 16.12.2 Const: It is a compile-time error if evaluation of a constant
-   * object results in an uncaught exception being thrown.
-   */
-  static const CheckedModeCompileTimeErrorCode
-      CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH = CheckedModeCompileTimeErrorCode(
-          'CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH',
-          "A value of type '{0}' can't be assigned to the field '{1}', which "
-              "has type '{2}'.");
-
-  /**
-   * 7.6.1 Generative Constructors: In checked mode, it is a dynamic type error
-   * if o is not <b>null</b> and the interface of the class of <i>o</i> is not a
-   * subtype of the static type of the field <i>v</i>.
-   *
-   * 16.12.2 Const: It is a compile-time error if evaluation of a constant
-   * object results in an uncaught exception being thrown.
-   *
-   * Parameters:
-   * 0: the name of the type of the initializer expression
-   * 1: the name of the type of the field
-   */
-  static const CheckedModeCompileTimeErrorCode
-      CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE = CheckedModeCompileTimeErrorCode(
-          'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
-          "The initializer type '{0}' can't be assigned to the field type "
-              "'{1}'.");
-
-  /**
-   * Parameters:
-   * 0: the type of the object being assigned.
-   * 1: the type of the variable being assigned to
-   */
-  // #### Description
-  //
-  // The analyzer produces this diagnostic when the evaluation of a constant
-  // expression would result in a `CastException`.
-  //
-  // #### Examples
-  //
-  // The following code produces this diagnostic because the value of `x` is an
-  // `int`, which can't be assigned to `y` because an `int` isn't a `String`:
-  //
-  // ```dart
-  // const Object x = 0;
-  // const String y = [!x!];
-  // ```
-  //
-  // #### Common fixes
-  //
-  // If the declaration of the constant is correct, then change the value being
-  // assigned to be of the correct type:
-  //
-  // ```dart
-  // const Object x = 0;
-  // const String y = '$x';
-  // ```
-  //
-  // If the assigned value is correct, then change the declaration to have the
-  // correct type:
-  //
-  // ```dart
-  // const Object x = 0;
-  // const int y = x;
-  // ```
-  static const CheckedModeCompileTimeErrorCode VARIABLE_TYPE_MISMATCH =
-      CheckedModeCompileTimeErrorCode(
-          'VARIABLE_TYPE_MISMATCH',
-          "A value of type '{0}' can't be assigned to a variable of type "
-              "'{1}'.",
-          hasPublishedDocs: true);
-
-  /**
-   * Initialize a newly created error code to have the given [name]. The message
-   * associated with the error will be created from the given [message]
-   * template. The correction associated with the error will be created from the
-   * given [correction] template.
-   */
-  const CheckedModeCompileTimeErrorCode(String name, String message,
-      {String correction, bool hasPublishedDocs})
-      : super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
-
-  @override
-  ErrorSeverity get errorSeverity =>
-      ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR.severity;
-
-  @override
-  ErrorType get type => ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR;
-}
-
-/**
  * The error codes used for compile time errors. The convention for this class
  * is for the name of the error code to indicate the problem that caused the
  * error to be generated and for the error message to explain what is wrong and,
@@ -1390,6 +1283,18 @@
           correction: "Try renaming either the type variable or the member.");
 
   /**
+   * 16.12.2 Const: It is a compile-time error if evaluation of a constant
+   * object results in an uncaught exception being thrown.
+   */
+  static const CompileTimeErrorCode CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH =
+      CompileTimeErrorCode(
+    'CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH',
+    "In a const constructor, a value of type '{0}' can't be assigned to the "
+        "field '{1}', which has type '{2}'.",
+    correction: "Try using a subtype, or removing the keyword 'const'.",
+  );
+
+  /**
    * Parameters:
    * 0: The type of the runtime value of the argument
    * 1: The static type of the parameter
@@ -1440,7 +1345,8 @@
       CompileTimeErrorCode(
           'CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH',
           "A value of type '{0}' can't be assigned to a parameter of type "
-              "'{1}'.",
+              "'{1}' in a const constructor.",
+          correction: "Try using a subtype, or removing the keyword 'const'.",
           hasPublishedDocs: true);
 
   /**
@@ -1669,6 +1575,24 @@
       'CONST_EVAL_TYPE_TYPE',
       "In constant expressions, operands of this operator must be of type "
           "'Type'.");
+  /**
+   * 7.6.1 Generative Constructors: In checked mode, it is a dynamic type error
+   * if o is not <b>null</b> and the interface of the class of <i>o</i> is not a
+   * subtype of the static type of the field <i>v</i>.
+   *
+   * 16.12.2 Const: It is a compile-time error if evaluation of a constant
+   * object results in an uncaught exception being thrown.
+   *
+   * Parameters:
+   * 0: the name of the type of the initializer expression
+   * 1: the name of the type of the field
+   */
+  static const CompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
+      CompileTimeErrorCode(
+          'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
+          "The initializer type '{0}' can't be assigned to the field type "
+              "'{1}' in a const constructor.",
+          correction: "Try using a subtype, or removing the 'const' keyword");
 
   /**
    * 6.2 Formal Parameters: It is a compile-time error if a formal parameter is
@@ -10009,6 +9933,51 @@
       hasPublishedDocs: true);
 
   /**
+   * Parameters:
+   * 0: the type of the object being assigned.
+   * 1: the type of the variable being assigned to
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when the evaluation of a constant
+  // expression would result in a `CastException`.
+  //
+  // #### Examples
+  //
+  // The following code produces this diagnostic because the value of `x` is an
+  // `int`, which can't be assigned to `y` because an `int` isn't a `String`:
+  //
+  // ```dart
+  // const Object x = 0;
+  // const String y = [!x!];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the declaration of the constant is correct, then change the value being
+  // assigned to be of the correct type:
+  //
+  // ```dart
+  // const Object x = 0;
+  // const String y = '$x';
+  // ```
+  //
+  // If the assigned value is correct, then change the declaration to have the
+  // correct type:
+  //
+  // ```dart
+  // const Object x = 0;
+  // const int y = x;
+  // ```
+  static const CompileTimeErrorCode VARIABLE_TYPE_MISMATCH =
+      CompileTimeErrorCode(
+          'VARIABLE_TYPE_MISMATCH',
+          "A value of type '{0}' can't be assigned to a const variable of type "
+              "'{1}'.",
+          correction: "Try using a subtype, or removing the 'const' keyword",
+          hasPublishedDocs: true);
+
+  /**
    * Let `C` be a generic class that declares a formal type parameter `X`, and
    * assume that `T` is a direct superinterface of `C`.
    *
diff --git a/pkg/analyzer/lib/src/error/dead_code_verifier.dart b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
index 4e5cebe..ad7fa1f 100644
--- a/pkg/analyzer/lib/src/error/dead_code_verifier.dart
+++ b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
@@ -153,7 +153,7 @@
   /// to the given [errorReporter] and will use the given [typeSystem] if one is
   /// provided.
   LegacyDeadCodeVerifier(this._errorReporter, {TypeSystemImpl typeSystem})
-      : this._typeSystem = typeSystem ??
+      : _typeSystem = typeSystem ??
             TypeSystemImpl(
               implicitCasts: true,
               isNonNullableByDefault: false,
@@ -389,8 +389,10 @@
         // dead, and it's a BreakStatement, then assume it is a statement
         // mandated by the language spec, there to avoid a
         // CASE_BLOCK_NOT_TERMINATED error.
-        if (allowMandated && i == size - 2 && nextStatement is BreakStatement) {
-          return;
+        if (allowMandated && i == size - 2) {
+          if (_isMandatedSwitchCaseTerminatingStatement(nextStatement)) {
+            return;
+          }
         }
         int offset = nextStatement.offset;
         int length = lastStatement.end - offset;
@@ -443,6 +445,21 @@
     }
     return false;
   }
+
+  static bool _isMandatedSwitchCaseTerminatingStatement(Statement node) {
+    if (node is BreakStatement ||
+        node is ContinueStatement ||
+        node is ReturnStatement) {
+      return true;
+    }
+    if (node is ExpressionStatement) {
+      var expression = node.expression;
+      if (expression is RethrowExpression || expression is ThrowExpression) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
 
 /// Helper for tracking dead code - [CatchClause]s and unreachable code.
diff --git a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
index 9c75de7..6a1c7a2 100644
--- a/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
+++ b/pkg/analyzer/lib/src/error/required_parameters_verifier.dart
@@ -40,6 +40,14 @@
 
   @override
   void visitMethodInvocation(MethodInvocation node) {
+    if (node.methodName.name == FunctionElement.CALL_METHOD_NAME) {
+      var targetType = node.realTarget?.staticType;
+      if (targetType is FunctionType) {
+        _check(targetType.parameters, node.argumentList, node.argumentList);
+        return;
+      }
+    }
+
     _check(
       _executableElement(node.methodName.staticElement)?.parameters,
       node.argumentList,
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index ed0cec8..ecf7baa 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -7,10 +7,8 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
@@ -29,8 +27,6 @@
     this._errorReporter,
   );
 
-  TypeProvider get _typeProvider => _libraryElement.typeProvider;
-
   TypeSystemImpl get _typeSystem => _libraryElement.typeSystem;
 
   void checkFunctionExpressionInvocation(FunctionExpressionInvocation node) {
@@ -237,8 +233,7 @@
 
         if (!_typeSystem.isSubtypeOf2(argType, boundType)) {
           if (_shouldAllowSuperBoundedTypes(typeName)) {
-            var replacedType =
-                (argType as TypeImpl).replaceTopAndBottom(_typeProvider);
+            var replacedType = _typeSystem.replaceTopAndBottom(argType);
             if (!identical(replacedType, argType) &&
                 _typeSystem.isSubtypeOf2(replacedType, boundType)) {
               // Bound is satisfied under super-bounded rules, so we're ok.
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index a8c359f..2cf4091 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -133,14 +133,14 @@
   AstBuilder(ErrorReporter errorReporter, this.fileUri, this.isFullAst,
       this._featureSet,
       [Uri uri])
-      : this.errorReporter = FastaErrorReporter(errorReporter),
-        this.enableNonNullable = _featureSet.isEnabled(Feature.non_nullable),
-        this.enableSpreadCollections =
+      : errorReporter = FastaErrorReporter(errorReporter),
+        enableNonNullable = _featureSet.isEnabled(Feature.non_nullable),
+        enableSpreadCollections =
             _featureSet.isEnabled(Feature.spread_collections),
-        this.enableControlFlowCollections =
+        enableControlFlowCollections =
             _featureSet.isEnabled(Feature.control_flow_collections),
-        this.enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
-        this.enableVariance = _featureSet.isEnabled(Feature.variance),
+        enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
+        enableVariance = _featureSet.isEnabled(Feature.variance),
         uri = uri ?? fileUri;
 
   NodeList<ClassMember> get currentDeclarationMembers {
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index a195ba9..98df2ee 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -230,8 +230,8 @@
         _requiredParametersVerifier = RequiredParametersVerifier(errorReporter),
         _duplicateDefinitionVerifier =
             DuplicateDefinitionVerifier(_currentLibrary, errorReporter) {
-    this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
-    this._hasExtUri = _currentLibrary.hasExtUri;
+    _isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
+    _hasExtUri = _currentLibrary.hasExtUri;
     _isInCatchClause = false;
     _isInStaticVariableDeclaration = false;
     _isInConstructorInitializer = false;
@@ -2463,8 +2463,7 @@
       // TODO(paulberry): this error should be based on the actual type of the
       // constant, not the static type.  See dartbug.com/21119.
       _errorReporter.reportErrorForNode(
-          CheckedModeCompileTimeErrorCode
-              .CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+          CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
           expression,
           [staticType, fieldType]);
     }
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 0cd4eb0..d5457b2 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -161,17 +161,17 @@
 
 abstract class PrintWriter {
   void newLine() {
-    this.print('\n');
+    print('\n');
   }
 
   void print(Object x);
 
   void printf(String fmt, List args) {
-    this.print(_printf(fmt, args));
+    print(_printf(fmt, args));
   }
 
   void println(String s) {
-    this.print(s);
-    this.newLine();
+    print(s);
+    newLine();
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index eb94d99..efd679e7 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -18,9 +18,9 @@
   JavaFile.fromUri(Uri uri) : this(path.context.fromUri(uri));
   JavaFile.relative(JavaFile base, String child) {
     if (child.isEmpty) {
-      this._path = base._path;
+      _path = base._path;
     } else {
-      this._path = path.context.join(base._path, child);
+      _path = path.context.join(base._path, child);
     }
   }
   @override
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index b57d7ea..d23a065 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -227,7 +227,7 @@
 
   /// Set the token with which the parse is to begin to the given [token].
   set currentToken(Token token) {
-    this._currentToken = token;
+    _currentToken = token;
   }
 
   /// Return `true` if the parser is to parse asserts in the initializer list of
@@ -293,7 +293,7 @@
 
   /// Set whether parser is to parse function bodies.
   set parseFunctionBodies(bool parseFunctionBodies) {
-    this._parseFunctionBodies = parseFunctionBodies;
+    _parseFunctionBodies = parseFunctionBodies;
   }
 
   /// Return the content of a string with the given literal representation. The
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 49cc989..0d0f8b1 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -292,71 +292,71 @@
       : _featureSet = featureSet,
         super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
-    this._promoteManager = TypePromotionManager(typeSystem);
-    this.nullableDereferenceVerifier = NullableDereferenceVerifier(
+    _promoteManager = TypePromotionManager(typeSystem);
+    nullableDereferenceVerifier = NullableDereferenceVerifier(
       typeSystem: typeSystem,
       errorReporter: errorReporter,
     );
-    this.boolExpressionVerifier = BoolExpressionVerifier(
+    boolExpressionVerifier = BoolExpressionVerifier(
       typeSystem: typeSystem,
       errorReporter: errorReporter,
       nullableDereferenceVerifier: nullableDereferenceVerifier,
     );
-    this._typedLiteralResolver = TypedLiteralResolver(
+    _typedLiteralResolver = TypedLiteralResolver(
         this, _featureSet, typeSystem, typeProvider,
         migratableAstInfoProvider: _migratableAstInfoProvider);
-    this.extensionResolver = ExtensionMemberResolver(this);
-    this.typePropertyResolver = TypePropertyResolver(this);
-    this.inferenceHelper = InvocationInferenceHelper(
+    extensionResolver = ExtensionMemberResolver(this);
+    typePropertyResolver = TypePropertyResolver(this);
+    inferenceHelper = InvocationInferenceHelper(
         resolver: this,
         flowAnalysis: _flowAnalysis,
         errorReporter: errorReporter,
         typeSystem: typeSystem,
         migrationResolutionHooks: migrationResolutionHooks);
-    this._assignmentExpressionResolver = AssignmentExpressionResolver(
+    _assignmentExpressionResolver = AssignmentExpressionResolver(
       resolver: this,
       flowAnalysis: _flowAnalysis,
     );
-    this._binaryExpressionResolver = BinaryExpressionResolver(
+    _binaryExpressionResolver = BinaryExpressionResolver(
       resolver: this,
       promoteManager: _promoteManager,
       flowAnalysis: _flowAnalysis,
     );
-    this._functionExpressionInvocationResolver =
+    _functionExpressionInvocationResolver =
         FunctionExpressionInvocationResolver(
       resolver: this,
     );
-    this._functionExpressionResolver = FunctionExpressionResolver(
+    _functionExpressionResolver = FunctionExpressionResolver(
       resolver: this,
       migrationResolutionHooks: migrationResolutionHooks,
       flowAnalysis: _flowAnalysis,
       promoteManager: _promoteManager,
     );
-    this._forResolver = ForResolver(
+    _forResolver = ForResolver(
       resolver: this,
       flowAnalysis: _flowAnalysis,
     );
-    this._postfixExpressionResolver = PostfixExpressionResolver(
+    _postfixExpressionResolver = PostfixExpressionResolver(
       resolver: this,
       flowAnalysis: _flowAnalysis,
     );
-    this._prefixExpressionResolver = PrefixExpressionResolver(
+    _prefixExpressionResolver = PrefixExpressionResolver(
       resolver: this,
       flowAnalysis: _flowAnalysis,
     );
-    this._yieldStatementResolver = YieldStatementResolver(
+    _yieldStatementResolver = YieldStatementResolver(
       resolver: this,
     );
-    this.nullSafetyDeadCodeVerifier = NullSafetyDeadCodeVerifier(
+    nullSafetyDeadCodeVerifier = NullSafetyDeadCodeVerifier(
       typeSystem,
       errorReporter,
       _flowAnalysis,
     );
-    this.elementResolver = ElementResolver(this,
+    elementResolver = ElementResolver(this,
         reportConstEvaluationErrors: reportConstEvaluationErrors,
         migratableAstInfoProvider: _migratableAstInfoProvider);
-    this.inferenceContext = InferenceContext._(this);
-    this.typeAnalyzer = StaticTypeAnalyzer(
+    inferenceContext = InferenceContext._(this);
+    typeAnalyzer = StaticTypeAnalyzer(
         this, featureSet, _flowAnalysis, migrationResolutionHooks);
   }
 
@@ -679,6 +679,7 @@
     // We do not visit the label because it needs to be visited in the context
     // of the statement.
     //
+    checkUnreachableNode(node);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
     _flowAnalysis?.breakStatement(node);
@@ -933,6 +934,7 @@
     // We do not visit the label because it needs to be visited in the context
     // of the statement.
     //
+    checkUnreachableNode(node);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
     _flowAnalysis?.continueStatement(node);
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 2ed64ad..efa21c7 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -330,7 +330,7 @@
 
   /// Set whether the library is documented.
   set documented(bool documented) {
-    this._documented = documented;
+    _documented = documented;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 16d82d2..105c95a 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -84,8 +84,8 @@
   /// a [uri] is given, then it will be used as the URI from which the source
   /// was derived, otherwise a `file:` URI will be created based on the [file].
   FileBasedSource(JavaFile file, [Uri uri])
-      : this.uri = uri ?? file.toURI(),
-        this.file = file,
+      : uri = uri ?? file.toURI(),
+        file = file,
         id = _idTable.putIfAbsent(
             '${uri ?? file.toURI()}@${file.getPath()}', () => _idTable.length);
 
diff --git a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
index 2ed4d3e..1858a9b 100644
--- a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
+++ b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
@@ -313,12 +313,12 @@
 
   @override
   void visitFunctionExpression(FunctionExpression node) {
-    bool inClosure = this._inClosure;
+    bool inClosure = _inClosure;
     try {
-      this._inClosure = true;
+      _inClosure = true;
       super.visitFunctionExpression(node);
     } finally {
-      this._inClosure = inClosure;
+      _inClosure = inClosure;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 20e1c69..4261e0c 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -671,7 +671,7 @@
   const Maturity._(this.name, {this.ordinal});
 
   @override
-  int compareTo(Maturity other) => this.ordinal - other.ordinal;
+  int compareTo(Maturity other) => ordinal - other.ordinal;
 }
 
 /// [LintRule]s that implement this interface want to process only some types
diff --git a/pkg/analyzer/lib/src/lint/util.dart b/pkg/analyzer/lib/src/lint/util.dart
index 7325d48..0644fb7 100644
--- a/pkg/analyzer/lib/src/lint/util.dart
+++ b/pkg/analyzer/lib/src/lint/util.dart
@@ -87,7 +87,7 @@
   FeatureSet featureSet;
 
   Spelunker(this.path, {IOSink sink, FeatureSet featureSet})
-      : this.sink = sink ?? stdout,
+      : sink = sink ?? stdout,
         featureSet = featureSet ?? FeatureSet.fromEnableFlags([]);
 
   void spelunk() {
diff --git a/pkg/analyzer/lib/src/source/path_filter.dart b/pkg/analyzer/lib/src/source/path_filter.dart
index 891d54d..62a490a 100644
--- a/pkg/analyzer/lib/src/source/path_filter.dart
+++ b/pkg/analyzer/lib/src/source/path_filter.dart
@@ -20,7 +20,7 @@
   /// Construct a new path filter rooted at [root] with [ignorePatterns].
   /// If [pathContext] is not specified, then the system path context is used.
   PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
-      : this.pathContext = pathContext ?? path.context {
+      : pathContext = pathContext ?? path.context {
     setIgnorePatterns(ignorePatterns);
   }
 
diff --git a/pkg/analyzer/lib/src/source/source_resource.dart b/pkg/analyzer/lib/src/source/source_resource.dart
index e240e80..39ef8c3 100644
--- a/pkg/analyzer/lib/src/source/source_resource.dart
+++ b/pkg/analyzer/lib/src/source/source_resource.dart
@@ -45,8 +45,8 @@
   /// a [uri] is given, then it will be used as the URI from which the source
   /// was derived, otherwise a `file:` URI will be created based on the [file].
   FileSource(File file, [Uri uri])
-      : this.uri = uri ?? file.toUri(),
-        this.file = file,
+      : uri = uri ?? file.toUri(),
+        file = file,
         id = _idTable.putIfAbsent(
             '${uri ?? file.toUri()}@${file.path}', () => _idTable.length);
 
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index df408cf..f82279c 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -20,7 +20,7 @@
   final int modificationStamp;
 
   StringSource(this._contents, String fullName, {Uri uri})
-      : this.fullName = fullName,
+      : fullName = fullName,
         uri = uri ?? (fullName == null ? null : Uri.file(fullName)),
         modificationStamp = DateTime.now().millisecondsSinceEpoch;
 
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 54a723b..18d2996 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -1,12 +1,15 @@
 // Copyright (c) 2015, 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.
-//
+
 // This file has been automatically generated.  Please do not edit it manually.
 // To regenerate the file, use the SDK script
 // "pkg/analyzer/tool/summary/generate.dart $IDL_FILE_PATH",
 // or "pkg/analyzer/tool/generate_files" for the analyzer package IDL/sources.
 
+// The generator sometimes generates unnecessary 'this' references.
+// ignore_for_file: unnecessary_this
+
 library analyzer.src.summary.format;
 
 import 'dart:convert' as convert;
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 31bfa9c..e948b37 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1,7 +1,7 @@
 // Copyright (c) 2015, 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.
-//
+
 // This file has been automatically generated.  Please do not edit it manually.
 // To regenerate the file, use the SDK script
 // "pkg/analyzer/tool/summary/generate.dart $IDL_FILE_PATH",
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 508743d..1c5a27b 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -15,7 +15,7 @@
   }
 
   void setBundle2(LinkedNodeBundleBuilder bundle2) {
-    if (this._bundle2 != null) {
+    if (_bundle2 != null) {
       throw StateError('Bundle2 may be set only once.');
     }
     _bundle2 = bundle2;
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index e956041..14ab9ad3 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -300,7 +300,7 @@
       return null;
     }
     var relativeUri = Uri.parse(relativeUriStr);
-    return resolveRelativeUri(this.uri, relativeUri);
+    return resolveRelativeUri(uri, relativeUri);
   }
 
   String _selectRelativeUri(
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 374cfb3..caeb168 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -150,14 +150,8 @@
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
   void removeBundle(LinkedBundleContext context) {
-    // TODO(scheglov) Use removeLibraries()
-    for (var uriStr in context.libraryMap.keys) {
-      libraryMap.remove(uriStr);
-      rootReference.removeChild(uriStr);
-    }
-
-    var classHierarchy = analysisSession.classHierarchy;
-    classHierarchy.removeOfLibraries(context.libraryMap.keys);
+    var uriStrList = context.libraryMap.keys.toList();
+    removeLibraries(uriStrList);
   }
 
   /// Remove libraries with the specified URIs from the reference tree, and
@@ -168,8 +162,9 @@
       rootReference.removeChild(uriStr);
     }
 
-    var classHierarchy = analysisSession.classHierarchy;
-    classHierarchy.removeOfLibraries(uriStrList);
+    var uriStrSet = uriStrList.toSet();
+    analysisSession.classHierarchy.removeOfLibraries(uriStrSet);
+    analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
   }
 
   /// Set optional informative data for the unit.
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index 22e4b56..18b35fdd8 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -484,7 +484,7 @@
   final BazelWorkspace workspace;
 
   BazelWorkspacePackage(String packageName, this.root, this.workspace)
-      : this._uriPrefix = 'package:$packageName/';
+      : _uriPrefix = 'package:$packageName/';
 
   @override
   bool contains(Source source) {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index d8d71f9..4ac4a2b 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,10 +1,10 @@
 name: analyzer
-version: 0.39.15
+version: 0.39.16-dev
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
 environment:
-  sdk: '>=2.6.0 <3.0.0'
+  sdk: '>=2.7.0 <3.0.0'
 
 dependencies:
   _fe_analyzer_shared: ^6.0.0
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
deleted file mode 100644
index 1ac317b..0000000
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright (c) 2016, 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 '../src/dart/resolution/driver_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
-  });
-}
-
-@reflectiveTest
-class CheckedModeCompileTimeErrorCodeTest extends DriverResolutionTest {
-  test_assertion_throws() async {
-    await assertErrorsInCode(r'''
-class A {
-  const A(int x, int y) : assert(x < y);
-}
-var v = const A(3, 2);
-''', [
-      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 61, 13),
-    ]);
-  }
-
-  test_fieldInitializerNotAssignable() async {
-    await assertErrorsInCode(r'''
-class A {
-  final int x;
-  const A() : x = '';
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 43, 2),
-      error(
-          CheckedModeCompileTimeErrorCode
-              .CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
-          43,
-          2),
-    ]);
-  }
-
-  test_fieldTypeMismatch() async {
-    await assertErrorsInCode(r'''
-class A {
-  const A(x) : y = x;
-  final int y;
-}
-var v = const A('foo');
-''', [
-      error(
-          CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
-          57,
-          14),
-    ]);
-  }
-
-  test_fieldTypeMismatch_generic() async {
-    await assertErrorsInCode(
-      r'''
-class C<T> {
-  final T x = y;
-  const C();
-}
-const int y = 1;
-var v = const C<String>();
-''',
-      [
-        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 27, 1),
-        error(
-            CheckedModeCompileTimeErrorCode
-                .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
-            70,
-            17),
-      ],
-    );
-  }
-
-  test_fieldTypeMismatch_unresolved() async {
-    await assertErrorsInCode(r'''
-class A {
-  const A(x) : y = x;
-  final Unresolved y;
-}
-var v = const A('foo');
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
-    ]);
-  }
-
-  test_fieldTypeOk_generic() async {
-    await assertErrorsInCode(
-      r'''
-class C<T> {
-  final T x = y;
-  const C();
-}
-const int y = 1;
-var v = const C<int>();
-''',
-      [
-        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 27, 1),
-      ],
-    );
-  }
-
-  test_fieldTypeOk_null() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  const A(x) : y = x;
-  final int y;
-}
-var v = const A(null);
-''');
-  }
-
-  test_fieldTypeOk_unresolved_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    await assertErrorsInCode(r'''
-class A {
-  const A(x) : y = x;
-  final Unresolved y;
-}
-var v = const A(null);
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
-    ]);
-  }
-
-  test_listElementTypeNotAssignable() async {
-    await assertErrorsInCode('''
-var v = const <String> [42];
-''', [
-      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 24, 2),
-    ]);
-  }
-
-  test_listLiteral_inferredElementType() async {
-    await assertErrorsInCode('''
-const Object x = [1];
-const List<String> y = x;
-''', [
-      error(CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 45, 1),
-    ]);
-  }
-
-  test_mapLiteral_inferredKeyType() async {
-    await assertErrorsInCode('''
-const Object x = {1: 1};
-const Map<String, dynamic> y = x;
-''', [
-      error(CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 56, 1),
-    ]);
-  }
-
-  test_mapLiteral_inferredValueType() async {
-    await assertErrorsInCode('''
-const Object x = {1: 1};
-const Map<dynamic, String> y = x;
-''', [
-      error(CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 56, 1),
-    ]);
-  }
-
-  test_parameterAssignable_null() async {
-    // Null is assignable to anything.
-    await assertNoErrorsInCode(r'''
-class A {
-  const A(int x);
-}
-var v = const A(null);''');
-  }
-
-  test_parameterAssignable_typeSubstitution() async {
-    await assertNoErrorsInCode(r'''
-class A<T> {
-  const A(T x);
-}
-var v = const A<int>(3);''');
-  }
-
-  test_parameterAssignable_undefined_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    await assertErrorsInCode(r'''
-class A {
-  const A(Unresolved x);
-}
-var v = const A(null);
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 20, 10),
-    ]);
-  }
-
-  test_parameterNotAssignable() async {
-    await assertErrorsInCode(r'''
-class A {
-  const A(int x);
-}
-var v = const A('foo');
-''', [
-      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 46, 5),
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 5),
-    ]);
-  }
-
-  test_parameterNotAssignable_typeSubstitution() async {
-    await assertErrorsInCode(r'''
-class A<T> {
-  const A(T x);
-}
-var v = const A<int>('foo');
-''', [
-      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 5),
-      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 52, 5),
-    ]);
-  }
-
-  test_parameterNotAssignable_undefined() async {
-    await assertErrorsInCode(r'''
-class A {
-  const A(Unresolved x);
-}
-var v = const A('foo');
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 20, 10),
-    ]);
-  }
-
-  test_redirectingConstructor_paramTypeMismatch() async {
-    await assertErrorsInCode(r'''
-class A {
-  const A.a1(x) : this.a2(x);
-  const A.a2(String x);
-}
-var v = const A.a1(0);
-''', [
-      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 74, 13),
-    ]);
-  }
-
-  test_superConstructor_paramTypeMismatch() async {
-    await assertErrorsInCode(r'''
-class C {
-  final double d;
-  const C(this.d);
-}
-class D extends C {
-  const D(d) : super(d);
-}
-const f = const D('0.0');
-''', [
-      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 106, 14),
-    ]);
-  }
-
-  test_topLevelVarAssignable_null() async {
-    await assertNoErrorsInCode('''
-const int x = null;
-''');
-  }
-
-  test_topLevelVarAssignable_undefined_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    await assertErrorsInCode('''
-const Unresolved x = null;
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 6, 10),
-    ]);
-  }
-
-  test_topLevelVarNotAssignable() async {
-    await assertErrorsInCode('''
-const int x = 'foo';
-''', [
-      error(CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 14, 5),
-      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 14, 5),
-    ]);
-  }
-
-  test_topLevelVarNotAssignable_undefined() async {
-    await assertErrorsInCode('''
-const Unresolved x = 'foo';
-''', [
-      error(CompileTimeErrorCode.UNDEFINED_CLASS, 6, 10),
-    ]);
-  }
-}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 9423c6c..b1fcee9 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -6880,9 +6880,7 @@
     InstanceCreationExpressionImpl expression =
         parseExpression('new a.b.c<C>()', errors: [
       expectedError(
-          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          8,
-          1)
+          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 8, 1)
     ]);
     expect(expression, isNotNull);
     expect(expression.keyword.keyword, Keyword.NEW);
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 4d5a888..42ff098 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -5,8 +5,6 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'all_the_rest_test.dart' as all_the_rest;
-import 'checked_mode_compile_time_error_code_test.dart'
-    as checked_mode_compile_time_error_code;
 // ignore: deprecated_member_use_from_same_package
 import 'constant_test.dart' as constant_test;
 import 'element_resolver_test.dart' as element_resolver_test;
@@ -35,7 +33,6 @@
 main() {
   defineReflectiveSuite(() {
     all_the_rest.main();
-    checked_mode_compile_time_error_code.main();
     constant_test.main();
     element_resolver_test.main();
     error_suppression.main();
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
index 17017c4..32093f7 100644
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ b/pkg/analyzer/test/src/command_line/arguments_test.dart
@@ -36,16 +36,28 @@
       '--packages=$defaultPackageFilePath',
     ];
     ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options = createContextBuilderOptions(result);
+    ContextBuilderOptions options =
+        createContextBuilderOptions(resourceProvider, result);
     expect(options, isNotNull);
-    expect(options.dartSdkSummaryPath, dartSdkSummaryPath);
+
+    expect(
+      options.defaultAnalysisOptionsFilePath,
+      endsWith(defaultAnalysisOptionsFilePath),
+    );
+    expect(
+      options.defaultPackageFilePath,
+      endsWith(defaultPackageFilePath),
+    );
+    expect(
+      options.dartSdkSummaryPath,
+      endsWith(dartSdkSummaryPath),
+    );
+
     Map<String, String> declaredVariables = options.declaredVariables;
     expect(declaredVariables, hasLength(2));
     expect(declaredVariables['foo'], '1');
     expect(declaredVariables['bar'], '2');
-    expect(
-        options.defaultAnalysisOptionsFilePath, defaultAnalysisOptionsFilePath);
-    expect(options.defaultPackageFilePath, defaultPackageFilePath);
+
     AnalysisOptionsImpl defaultOptions = options.defaultOptions;
     expect(defaultOptions, isNotNull);
     expect(defaultOptions.strongMode, true);
@@ -58,7 +70,8 @@
     defineAnalysisArguments(parser);
     List<String> args = [];
     ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options = createContextBuilderOptions(result);
+    ContextBuilderOptions options =
+        createContextBuilderOptions(resourceProvider, result);
     expect(options, isNotNull);
     expect(options.dartSdkSummaryPath, isNull);
     expect(options.declaredVariables, isEmpty);
@@ -130,7 +143,8 @@
       '--implicit-casts',
     ];
     ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options = createContextBuilderOptions(result);
+    ContextBuilderOptions options =
+        createContextBuilderOptions(resourceProvider, result);
     expect(options, isNotNull);
     AnalysisOptionsImpl defaultOptions = options.defaultOptions;
     expect(defaultOptions, isNotNull);
@@ -144,7 +158,8 @@
       '--no-implicit-casts',
     ];
     ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options = createContextBuilderOptions(result);
+    ContextBuilderOptions options =
+        createContextBuilderOptions(resourceProvider, result);
     expect(options, isNotNull);
     AnalysisOptionsImpl defaultOptions = options.defaultOptions;
     expect(defaultOptions, isNotNull);
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 816bd11..3016530 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -105,7 +105,7 @@
     defineAnalysisArguments(argParser);
     ArgResults argResults = argParser.parse(['--$lintsFlag']);
     var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(argResults));
+        options: createContextBuilderOptions(resourceProvider, argResults));
 
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     expected.lint = true;
@@ -130,7 +130,7 @@
     defineAnalysisArguments(argParser);
     ArgResults argResults = argParser.parse(['--no-$lintsFlag']);
     var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(argResults));
+        options: createContextBuilderOptions(resourceProvider, argResults));
 
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     expected.lint = false;
@@ -155,7 +155,7 @@
     defineAnalysisArguments(argParser);
     ArgResults argResults = argParser.parse([]);
     var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(argResults));
+        options: createContextBuilderOptions(resourceProvider, argResults));
 
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     expected.lint = true;
@@ -180,7 +180,7 @@
     defineAnalysisArguments(argParser);
     ArgResults argResults = argParser.parse([]);
     var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(argResults));
+        options: createContextBuilderOptions(resourceProvider, argResults));
 
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
     expected.lint = false;
@@ -599,7 +599,7 @@
     ArgParser argParser = ArgParser();
     defineAnalysisArguments(argParser);
     ArgResults argResults = argParser.parse([]);
-    builderOptions = createContextBuilderOptions(argResults);
+    builderOptions = createContextBuilderOptions(resourceProvider, argResults);
     builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
         options: builderOptions);
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 718e234..37af8b4 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -39,12 +39,12 @@
   @override
   bool operator ==(Object result) {
     return result is SearchResult &&
-        result.kind == this.kind &&
-        result.isResolved == this.isResolved &&
-        result.isQualified == this.isQualified &&
-        result.offset == this.offset &&
-        result.length == this.length &&
-        result.enclosingElement == this.enclosingElement;
+        result.kind == kind &&
+        result.isResolved == isResolved &&
+        result.isQualified == isQualified &&
+        result.offset == offset &&
+        result.length == length &&
+        result.enclosingElement == enclosingElement;
   }
 
   @override
diff --git a/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart b/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
new file mode 100644
index 0000000..e3a64cf
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
@@ -0,0 +1,135 @@
+// Copyright (c) 2020, 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/dart/element/null_safety_understanding_flag.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/type_system_test.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceTopBottomLegacyTest);
+    defineReflectiveTests(ReplaceTopBottomNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceTopBottomLegacyTest extends AbstractTypeSystemTest {
+  test_contravariant_bottom() {
+    // Not contravariant.
+    _check(nullStar, 'Null*');
+
+    _check(
+      functionTypeStar(returnType: intStar, parameters: [
+        requiredParameter(type: nullStar),
+      ]),
+      'int* Function(dynamic)*',
+    );
+  }
+
+  test_covariant_top() {
+    _check(objectStar, 'Null*');
+    _check(dynamicNone, 'Null*');
+    _check(voidNone, 'Null*');
+
+    _check(futureOrStar(objectStar), 'Null*');
+    _check(futureOrStar(dynamicNone), 'Null*');
+    _check(futureOrStar(voidNone), 'Null*');
+    _check(futureOrStar(futureOrStar(voidNone)), 'Null*');
+
+    _check(
+      functionTypeStar(returnType: intStar, parameters: [
+        requiredParameter(
+          type: functionTypeStar(returnType: intStar, parameters: [
+            requiredParameter(type: objectStar),
+          ]),
+        ),
+      ]),
+      'int* Function(int* Function(Null*)*)*',
+      typeStr: 'int* Function(int* Function(Object*)*)*',
+    );
+
+    _check(listStar(intStar), 'List<int*>*');
+  }
+
+  void _check(DartType type, String expectedStr, {String typeStr}) {
+    NullSafetyUnderstandingFlag.enableNullSafetyTypes(() {
+      if (typeStr != null) {
+        expect(_typeString(type), typeStr);
+      }
+
+      var result = typeSystem.replaceTopAndBottom(type);
+      var resultStr = _typeString(result);
+      expect(resultStr, expectedStr);
+    });
+  }
+
+  String _typeString(TypeImpl type) {
+    return type.getDisplayString(withNullability: true);
+  }
+}
+
+@reflectiveTest
+class ReplaceTopBottomNullSafetyTest extends AbstractTypeSystemNullSafetyTest {
+  test_contravariant_bottom() {
+    // Not contravariant.
+    _check(neverNone, 'Never');
+
+    _check(
+      functionTypeNone(returnType: intNone, parameters: [
+        requiredParameter(type: neverNone),
+      ]),
+      'int Function(Object?)',
+    );
+  }
+
+  test_covariant_top() {
+    _check(objectQuestion, 'Never');
+    _check(objectStar, 'Never');
+    _check(dynamicNone, 'Never');
+    _check(voidNone, 'Never');
+
+    _check(futureOrNone(objectQuestion), 'Never');
+    _check(futureOrNone(objectStar), 'Never');
+    _check(futureOrNone(dynamicNone), 'Never');
+    _check(futureOrNone(voidNone), 'Never');
+    _check(futureOrNone(futureOrNone(voidNone)), 'Never');
+
+    _check(
+      functionTypeNone(returnType: intNone, parameters: [
+        requiredParameter(
+          type: functionTypeNone(returnType: intNone, parameters: [
+            requiredParameter(type: objectQuestion),
+          ]),
+        ),
+      ]),
+      'int Function(int Function(Never))',
+      typeStr: 'int Function(int Function(Object?))',
+    );
+
+    _check(listNone(intNone), 'List<int>');
+    _check(listNone(intQuestion), 'List<int?>');
+    _check(listQuestion(intNone), 'List<int>?');
+    _check(listQuestion(intQuestion), 'List<int?>?');
+  }
+
+  void _check(DartType type, String expectedStr, {String typeStr}) {
+    NullSafetyUnderstandingFlag.enableNullSafetyTypes(() {
+      if (typeStr != null) {
+        expect(_typeString(type), typeStr);
+      }
+
+      var result = typeSystem.replaceTopAndBottom(type);
+      var resultStr = _typeString(result);
+      expect(resultStr, expectedStr);
+    });
+  }
+
+  String _typeString(TypeImpl type) {
+    return type.getDisplayString(withNullability: true);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 0d31f54..f59885f 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -17,6 +17,7 @@
 import 'normalize_type_test.dart' as normalize_type;
 import 'nullability_eliminator_test.dart' as nullability_eliminator;
 import 'nullable_test.dart' as nullable;
+import 'replace_top_bottom_test.dart' as replace_top_bottom;
 import 'runtime_type_equality_test.dart' as runtime_type_equality;
 import 'subtype_test.dart' as subtype;
 import 'top_merge_test.dart' as top_merge;
@@ -42,6 +43,7 @@
     normalize_type.main();
     nullability_eliminator.main();
     nullable.main();
+    replace_top_bottom.main();
     runtime_type_equality.main();
     subtype.main();
     top_merge.main();
diff --git a/pkg/analyzer/test/src/dart/element/type_visitor_test.dart b/pkg/analyzer/test/src/dart/element/type_visitor_test.dart
index 40352a8..2989a22 100644
--- a/pkg/analyzer/test/src/dart/element/type_visitor_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_visitor_test.dart
@@ -88,7 +88,7 @@
   }
 
   void test_functionType_typeFormal_noBound() {
-    final T = this.typeParameter('T');
+    final T = typeParameter('T');
     final type = functionType(
         returnType: dynamicType,
         typeFormals: [T],
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index eb8b108..e16cbbf 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -89,6 +89,37 @@
     assertErrorsInResolvedUnit(result, []);
   }
 
+  test_changeFile_resolution_flushInheritanceManager() async {
+    newFile(aPath, content: r'''
+class A {
+  final int foo = 0;
+}
+''');
+
+    newFile(bPath, content: r'''
+import 'a.dart';
+
+void f(A a) {
+  a.foo = 1;
+}
+''');
+
+    result = await resolveFile(bPath);
+    assertErrorsInResolvedUnit(result, [
+      error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 36, 3),
+    ]);
+
+    newFile(aPath, content: r'''
+class A {
+  int foo = 0;
+}
+''');
+    fileResolver.changeFile(aPath);
+
+    result = await resolveFile(bPath);
+    assertErrorsInResolvedUnit(result, []);
+  }
+
   test_changePartFile_refreshedFiles() async {
     newFile(aPath, content: r'''
 part 'b.dart';
diff --git a/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
index 9bb1581..495c89a 100644
--- a/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/ast_rewrite_test.dart
@@ -138,8 +138,8 @@
   prefix.A.named<int>(0);
 }
 ''', [
-      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          50, 5),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 50,
+          5),
     ]);
 
     var importFind = findElement.importFind('package:test/a.dart');
@@ -220,8 +220,8 @@
   A.named<int, String>(0);
 }
 ''', [
-      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          52, 13),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 52,
+          13),
     ]);
 
     var creation = findNode.instanceCreation('named<int, String>(0);');
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 85e42d9..d7de1d4 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -42,8 +42,8 @@
   new Foo.bar<int>();
 }
 ''', [
-      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          53, 5),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 53,
+          5),
     ]);
 
     var creation = findNode.instanceCreation('Foo.bar<int>');
@@ -70,8 +70,8 @@
   new p.Foo.bar<int>();
 }
 ''', [
-      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          44, 3),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 44,
+          3),
     ]);
 
     // TODO(brianwilkerson) Test this more carefully after we can re-write the
@@ -97,8 +97,8 @@
   Foo.bar<int>();
 }
 ''', [
-      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          49, 5),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 49,
+          5),
     ]);
 
     var creation = findNode.instanceCreation('Foo.bar<int>');
@@ -129,8 +129,8 @@
   p.Foo.bar<int>();
 }
 ''', [
-      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
-          43, 5),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 43,
+          5),
     ]);
 
     var import = findElement.import('package:test/a.dart');
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 513338a..b5d5f19 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -637,8 +637,7 @@
 }
 ''', [
       error(
-          CompileTimeErrorCode
-              .UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+          CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
           71,
           3),
       error(CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS, 74, 3),
@@ -1654,8 +1653,7 @@
   foo<int, double>();
 }
 ''', [
-      error(
-          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 32, 13),
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD, 32, 13),
     ]);
     var invocation = findNode.methodInvocation('foo<int, double>();');
     assertTypeArgumentTypes(invocation, ['dynamic']);
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
index a27736a..f4d6e53 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
@@ -30,8 +30,7 @@
 int f(A a) => a();
 ''', [
       error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 110, 1),
-      error(
-          CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 110, 1),
+      error(CompileTimeErrorCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, 110, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_field_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_field_type_mismatch_test.dart
new file mode 100644
index 0000000..43efe7b
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_field_type_mismatch_test.dart
@@ -0,0 +1,97 @@
+// 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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstConstructorFieldTypeMismatchTest);
+  });
+}
+
+@reflectiveTest
+class ConstConstructorFieldTypeMismatchTest extends DriverResolutionTest {
+  test_assignable_generic() async {
+    await assertErrorsInCode(
+      r'''
+class C<T> {
+  final T x = y;
+  const C();
+}
+const int y = 1;
+var v = const C<int>();
+''',
+      [
+        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 27, 1),
+      ],
+    );
+  }
+
+  test_assignable_nullValue() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  const A(x) : y = x;
+  final int y;
+}
+var v = const A(null);
+''');
+  }
+
+  test_assignable_unresolvedFieldAndNullValue() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A(x) : y = x;
+  final Unresolved y;
+}
+var v = const A(null);
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
+    ]);
+  }
+
+  test_notAssignable() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A(x) : y = x;
+  final int y;
+}
+var v = const A('foo');
+''', [
+      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, 57, 14),
+    ]);
+  }
+
+  test_notAssignable_generic() async {
+    await assertErrorsInCode(
+      r'''
+class C<T> {
+  final T x = y;
+  const C();
+}
+const int y = 1;
+var v = const C<String>();
+''',
+      [
+        error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 27, 1),
+        error(
+            CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, 70, 17),
+      ],
+    );
+  }
+
+  test_notAssignable_unresolved() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A(x) : y = x;
+  final Unresolved y;
+}
+var v = const A('foo');
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
index ed901d3..f2f4409 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
@@ -16,7 +16,7 @@
 
 @reflectiveTest
 class ConstConstructorParamTypeMismatchTest extends DriverResolutionTest {
-  test_assignable_null() async {
+  test_assignable_fieldFormal_null() async {
     // Null is assignable to anything (before null safety).
     await assertNoErrorsInCode(r'''
 class A {
@@ -27,7 +27,7 @@
 ''');
   }
 
-  test_assignable_omittedType() async {
+  test_assignable_fieldFormal_omittedType() async {
     // If a field is declared without a type, and no initializer, it's type is
     // dynamic.
     await assertNoErrorsInCode(r'''
@@ -39,7 +39,7 @@
 ''');
   }
 
-  test_assignable_subtype() async {
+  test_assignable_fieldFormal_subtype() async {
     await assertNoErrorsInCode(r'''
 class A {
   const A();
@@ -55,7 +55,7 @@
 ''');
   }
 
-  test_assignable_typedef() async {
+  test_assignable_fieldFormal_typedef() async {
     // foo has the type dynamic -> dynamic, so it is not assignable to A.f.
     await assertErrorsInCode(r'''
 typedef String Int2String(int x);
@@ -71,7 +71,7 @@
     ]);
   }
 
-  test_assignable_typeSubstitution() async {
+  test_assignable_fieldFormal_typeSubstitution() async {
     await assertNoErrorsInCode(r'''
 class A<T> {
   final T x;
@@ -81,7 +81,7 @@
 ''');
   }
 
-  test_assignable_unresolved_null() async {
+  test_assignable_fieldFormal_unresolved_null() async {
     // Null always passes runtime type checks, even when the type is
     // unresolved.
     await assertErrorsInCode(r'''
@@ -95,6 +95,47 @@
     ]);
   }
 
+  test_assignable_null() async {
+    // Null is assignable to anything (before null safety).
+    await assertNoErrorsInCode(r'''
+class A {
+  const A(int x);
+}
+var v = const A(null);''');
+  }
+
+  test_assignable_typeSubstitution() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  const A(T x);
+}
+var v = const A<int>(3);''');
+  }
+
+  test_assignable_undefined() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A(Unresolved x);
+}
+var v = const A('foo');
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 20, 10),
+    ]);
+  }
+
+  test_assignable_undefined_null() async {
+    // Null always passes runtime type checks, even when the type is
+    // unresolved.
+    await assertErrorsInCode(r'''
+class A {
+  const A(Unresolved x);
+}
+var v = const A(null);
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 20, 10),
+    ]);
+  }
+
   test_int_to_double_reference_from_other_library_other_file_after() async {
     newFile('/test/lib/other.dart', content: '''
 import 'test.dart';
@@ -180,7 +221,7 @@
 ''');
   }
 
-  test_notAssignable_optional() async {
+  test_notAssignable_fieldFormal_optional() async {
     await assertErrorsInCode(r'''
 class A {
   final int x;
@@ -193,7 +234,7 @@
     ]);
   }
 
-  test_notAssignable_supertype() async {
+  test_notAssignable_fieldFormal_supertype() async {
     await assertErrorsInCode(r'''
 class A {
   const A();
@@ -212,7 +253,7 @@
     ]);
   }
 
-  test_notAssignable_typedef() async {
+  test_notAssignable_fieldFormal_typedef() async {
     // foo has type String -> int, so it is not assignable to A.f
     // (A.f requires it to be int -> String).
     await assertErrorsInCode(r'''
@@ -229,7 +270,7 @@
     ]);
   }
 
-  test_notAssignable_unrelated() async {
+  test_notAssignable_fieldFormal_unrelated() async {
     await assertErrorsInCode(r'''
 class A {
   final int x;
@@ -242,7 +283,7 @@
     ]);
   }
 
-  test_notAssignable_unresolved() async {
+  test_notAssignable_fieldFormal_unresolved() async {
     await assertErrorsInCode(r'''
 class A {
   final Unresolved x;
@@ -253,4 +294,28 @@
       error(CompileTimeErrorCode.UNDEFINED_CLASS, 18, 10),
     ]);
   }
+
+  test_notAssignable_typeSubstitution() async {
+    await assertErrorsInCode(r'''
+class A<T> {
+  const A(T x);
+}
+var v = const A<int>('foo');
+''', [
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 5),
+      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 52, 5),
+    ]);
+  }
+
+  test_notAssignable_unrelated() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A(int x);
+}
+var v = const A('foo');
+''', [
+      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 46, 5),
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 5),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
index 37c2845..b7517ec 100644
--- a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
@@ -23,6 +23,17 @@
 
 @reflectiveTest
 class ConstEvalThrowsExceptionTest extends DriverResolutionTest {
+  test_assertInitializerThrows() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A(int x, int y) : assert(x < y);
+}
+var v = const A(3, 2);
+''', [
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 61, 13),
+    ]);
+  }
+
   test_CastError_intToDouble_constructor_importAnalyzedAfter() async {
     // See dartbug.com/35993
     newFile('/test/lib/other.dart', content: '''
@@ -280,6 +291,33 @@
     ]);
   }
 
+  test_redirectingConstructor_paramTypeMismatch() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A.a1(x) : this.a2(x);
+  const A.a2(String x);
+}
+var v = const A.a1(0);
+''', [
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 74, 13),
+    ]);
+  }
+
+  test_superConstructor_paramTypeMismatch() async {
+    await assertErrorsInCode(r'''
+class C {
+  final double d;
+  const C(this.d);
+}
+class D extends C {
+  const D(d) : super(d);
+}
+const f = const D('0.0');
+''', [
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 106, 14),
+    ]);
+  }
+
   test_symbolConstructor_badStringArgument() async {
     await assertErrorsInCode(r'''
 var s1 = const Symbol('3');
diff --git a/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart
new file mode 100644
index 0000000..b7145d9
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, 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 '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstFieldInitializerNotAssignableTest);
+  });
+}
+
+@reflectiveTest
+class ConstFieldInitializerNotAssignableTest extends DriverResolutionTest {
+  test_assignable_subtype() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  final num x;
+  const A() : x = 1;
+}
+''');
+  }
+
+  test_notAssignable_unrelated() async {
+    await assertErrorsInCode(r'''
+class A {
+  final int x;
+  const A() : x = '';
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, 43, 2),
+      error(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, 43, 2),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart
index 73430bb..4736c9a 100644
--- a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart
@@ -15,6 +15,74 @@
 
 @reflectiveTest
 class CouldNotInferTest extends DriverResolutionTest {
+  test_constructors_inferenceFBounded() async {
+    await assertErrorsInCode('''
+class C<T> {}
+
+class P<T extends C<T>, U extends C<U>> {
+  T t;
+  U u;
+  P(this.t, this.u);
+  P._();
+  P<U, T> get reversed => new P(u, t);
+}
+
+main() {
+  P._();
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 154, 3),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 154, 1),
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 154, 3),
+    ]);
+  }
+
+  test_constructors_inferFromArguments_argumentNotAssignable() async {
+    await assertErrorsInCode('''
+class A {}
+
+typedef T F<T>();
+
+class C<T extends A> {
+  C(F<T> f);
+}
+
+class NotA {}
+NotA myF() => null;
+
+main() {
+  var x = C(myF);
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 120, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 124, 1),
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 124, 1),
+    ]);
+  }
+
+  test_downwardInference_fixes_noUpwardsErrors() async {
+    await assertErrorsInCode(r'''
+import 'dart:math';
+// T max<T extends num>(T x, T y);
+main() {
+  num x;
+  dynamic y;
+
+  num a = max(x, y);
+  Object b = max(x, y);
+  dynamic c = max(x, y);
+  var d = max(x, y);
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 93, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 117, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 142, 1),
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 146, 3),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 163, 1),
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 167, 3),
+    ]);
+  }
+
   test_function() async {
     await assertErrorsInCode(r'''
 T f<T>(T t) => null;
@@ -25,7 +93,7 @@
   }
 
   test_functionType() async {
-    await assertErrorsInCode(r'''
+    await assertErrorsInCode('''
 T Function<T>(T) f;
 main() { f(<S>(S s) => s); }
 ''', [
@@ -33,6 +101,141 @@
     ]);
   }
 
+  test_functionType_allSameSubtype() async {
+    await assertNoErrorsInCode(r'''
+external T f<T extends num>(T a, T b);
+void g(int cb(int a, int b)) {}
+void main() {
+  g(f);
+}
+''');
+  }
+
+  test_functionType_parameterIsBound_returnIsBound() async {
+    await assertNoErrorsInCode(r'''
+external T f<T extends num>(T a, T b);
+void g(num cb(num a, num b)) {}
+void main() {
+  g(f);
+}
+''');
+  }
+
+  test_functionType_parameterIsObject_returnIsBound() async {
+    await assertErrorsInCode('''
+external T f<T extends num>(T a, T b);
+void g(num cb(Object a, Object b)) {}
+void main() {
+  g(f);
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 95, 1),
+      error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 95, 1),
+    ]);
+  }
+
+  test_functionType_parameterIsObject_returnIsBound_prefixedFunction() async {
+    newFile('/test/lib/a.dart', content: '''
+external T f<T extends num>(T a, T b);
+''');
+    await assertErrorsInCode('''
+import 'a.dart' as a;
+void g(num cb(Object a, Object b)) {}
+void main() {
+  g(a.f);
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 78, 3),
+      error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 78, 3),
+    ]);
+  }
+
+  test_functionType_parameterIsObject_returnIsSubtype() async {
+    await assertErrorsInCode('''
+external T f<T extends num>(T a, T b);
+void g(int cb(Object a, Object b)) {}
+void main() {
+  g(f);
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 95, 1),
+      error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 95, 1),
+    ]);
+  }
+
+  test_functionType_parameterIsObject_returnIsSubtype_tearOff() async {
+    await assertErrorsInCode('''
+class C {
+  T m<T extends num>(T x, T y) {
+    throw 'error';
+  }
+}
+void g(int cb(Object a, Object b)) {}
+void main() {
+  g(C().m);
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 124, 5),
+    ]);
+  }
+
+  test_functionType_parameterIsSubtype_returnIsBound() async {
+    await assertNoErrorsInCode(r'''
+external T f<T extends num>(T a, T b);
+void g(num cb(int a, int b)) {}
+void main() {
+  g(f);
+}
+''');
+  }
+
+  test_functionType_parameterIsSubtype_returnIsObject() async {
+    await assertNoErrorsInCode('''
+external T f<T extends num>(T a, T b);
+void g(Object cb(int a, int b)) {}
+void main() {
+  g(f);
+}
+''');
+  }
+
+  test_functionType_parametersAreSubtypes_returnIsBound() async {
+    await assertNoErrorsInCode('''
+external T f<T extends num>(T a, T b);
+void g(num cb(int a, double b)) {}
+void main() {
+  g(f);
+}
+''');
+  }
+
+  test_functionType_parametersAreSubtypes_returnIsOne() async {
+    await assertErrorsInCode('''
+external T f<T extends num>(T a, T b);
+void g(int cb(int a, double b)) {}
+void main() {
+  g(f);
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 92, 1),
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 92, 1),
+    ]);
+  }
+
+  test_genericMethods_correctlyRecognizeGenericUpperBound() async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
+    await assertErrorsInCode(r'''
+class Foo<T extends Pattern> {
+  U method<U extends T>(U u) => u;
+}
+main() {
+  new Foo<String>()./*error:COULD_NOT_INFER*/method(42);
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 122, 6),
+    ]);
+  }
+
   test_method() async {
     await assertErrorsInCode(r'''
 class C {
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
index 8c097ab..4a4c77c 100644
--- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -316,61 +316,6 @@
     ]);
   }
 
-  test_deadFinalBreakInCase() async {
-    await assertNoErrorsInCode(r'''
-f() {
-  switch (true) {
-  case true:
-    try {
-      print(1);
-    } finally {
-      return;
-    }
-    break;
-  default:
-    break;
-  }
-}''');
-  }
-
-  test_deadFinalReturnInCase() async {
-    await assertErrorsInCode(r'''
-f() {
-  switch (true) {
-  case true:
-    try {
-      print(1);
-    } finally {
-      return;
-    }
-    return;
-  default:
-    break;
-  }
-}''', [
-      error(HintCode.DEAD_CODE, 103, 7),
-    ]);
-  }
-
-  test_deadFinalStatementInCase() async {
-    await assertErrorsInCode(r'''
-f() {
-  switch (true) {
-  case true:
-    try {
-      print(1);
-    } finally {
-      return;
-    }
-    throw 'msg';
-  default:
-    break;
-  }
-}''', [
-      error(HintCode.DEAD_CODE, 103, 12),
-    ]);
-  }
-
   test_deadOperandLHS_and() async {
     await assertErrorsInCode(r'''
 f() {
@@ -805,6 +750,97 @@
       error(HintCode.DEAD_CODE, 41, 9),
     ]);
   }
+
+  test_switchCase_final_break() async {
+    var expectedErrors = expectedErrorsByNullability(nullable: [
+      error(HintCode.DEAD_CODE, 96, 6),
+    ], legacy: []);
+    await assertErrorsInCode(r'''
+void f(int a) {
+  switch (a) {
+    case 0:
+      try {} finally {
+        return;
+      }
+      break;
+  }
+}
+''', expectedErrors);
+  }
+
+  test_switchCase_final_continue() async {
+    var expectedErrors = expectedErrorsByNullability(nullable: [
+      error(HintCode.DEAD_CODE, 140, 9),
+    ], legacy: []);
+    await assertErrorsInCode(r'''
+void f(int a) {
+  for (var i = 0; i < 2; i++) {
+    switch (a) {
+      case 0:
+        try {} finally {
+          return;
+        }
+        continue;
+    }
+  }
+}
+''', expectedErrors);
+  }
+
+  test_switchCase_final_rethrow() async {
+    var expectedErrors = expectedErrorsByNullability(nullable: [
+      error(HintCode.DEAD_CODE, 142, 8),
+    ], legacy: []);
+    await assertErrorsInCode(r'''
+void f(int a) {
+  try {
+    // empty
+  } on int {
+    switch (a) {
+      case 0:
+        try {} finally {
+          return;
+        }
+        rethrow;
+    }
+  }
+}
+''', expectedErrors);
+  }
+
+  test_switchCase_final_return() async {
+    var expectedErrors = expectedErrorsByNullability(nullable: [
+      error(HintCode.DEAD_CODE, 96, 7),
+    ], legacy: []);
+    await assertErrorsInCode(r'''
+void f(int a) {
+  switch (a) {
+    case 0:
+      try {} finally {
+        return;
+      }
+      return;
+  }
+}
+''', expectedErrors);
+  }
+
+  test_switchCase_final_throw() async {
+    var expectedErrors = expectedErrorsByNullability(nullable: [
+      error(HintCode.DEAD_CODE, 96, 8),
+    ], legacy: []);
+    await assertErrorsInCode(r'''
+void f(int a) {
+  switch (a) {
+    case 0:
+      try {} finally {
+        return;
+      }
+      throw 0;
+  }
+}
+''', expectedErrors);
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart
new file mode 100644
index 0000000..b3fba28
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_instance_creation_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2020, 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:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InferenceFailureOnInstanceCreationTest);
+  });
+}
+
+@reflectiveTest
+class InferenceFailureOnInstanceCreationTest extends DriverResolutionTest
+    with PackageMixin {
+  @override
+  AnalysisOptionsImpl get analysisOptions =>
+      AnalysisOptionsImpl()..strictInference = true;
+
+  test_constructorNames_named() async {
+    await assertErrorsInCode('''
+import 'dart:collection';
+void f() {
+  HashMap.from({1: 1, 2: 2, 3: 3});
+}
+''', [
+      error(HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, 39, 12),
+    ]);
+    expect(result.errors[0].message, contains("'HashMap.from'"));
+  }
+
+  test_constructorNames_unnamed() async {
+    await assertErrorsInCode('''
+import 'dart:collection';
+void f() {
+  HashMap();
+}
+''', [
+      error(HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, 39, 7),
+    ]);
+    expect(result.errors[0].message, contains("'HashMap'"));
+  }
+
+  test_explicitTypeArgument() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:collection';
+void f() {
+  HashMap<int, int>();
+}
+''');
+  }
+
+  test_missingTypeArgument_downwardInference() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:collection';
+HashMap<int, int> f() {
+  return HashMap();
+}
+''');
+  }
+
+  test_missingTypeArgument_noInference() async {
+    await assertErrorsInCode(r'''
+import 'dart:collection';
+void f() {
+  HashMap();
+}
+''', [
+      error(HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, 39, 7),
+    ]);
+  }
+
+  test_missingTypeArgument_noInference_optionalTypeArgs() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+class C<T> {}
+void f() {
+  C();
+}
+''');
+  }
+
+  test_missingTypeArgument_upwardInference() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:collection';
+void f() {
+  HashMap.of({1: 1, 2: 2, 3: 3});
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
index d64dcf9..c040a2f 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
@@ -309,6 +309,18 @@
     ]);
   }
 
+  test_function_call() async {
+    await assertErrorsInCode(r'''
+void f({required int a}) {}
+
+main() {
+  f.call();
+}
+''', [
+      error(CompileTimeErrorCode.MISSING_REQUIRED_ARGUMENT, 46, 2),
+    ]);
+  }
+
   test_functionInvocation() async {
     await assertErrorsInCode(r'''
 void Function({required int a}) f() => throw '';
diff --git a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
index ec53808..78442d4 100644
--- a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
@@ -1030,7 +1030,6 @@
       break;
     case 2:
       continue L;
-      break;
     default:
       v = 0;
   }
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index cc08fbb..5346a05 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -59,6 +59,8 @@
     as conflicting_type_variable_and_container;
 import 'conflicting_type_variable_and_member_test.dart'
     as conflicting_type_variable_and_member;
+import 'const_constructor_field_type_mismatch_test.dart'
+    as const_constructor_field_type_mismatch;
 import 'const_constructor_param_type_mismatch_test.dart'
     as const_constructor_param_type_mismatch;
 import 'const_constructor_with_field_initialized_by_non_const_test.dart'
@@ -77,6 +79,8 @@
     as const_eval_type_bool_num_string;
 import 'const_eval_type_bool_test.dart' as const_eval_type_bool;
 import 'const_eval_type_num_test.dart' as const_eval_type_num;
+import 'const_field_initializer_not_assignable_test.dart'
+    as const_field_initializer_not_assignable;
 import 'const_formal_parameter_test.dart' as const_formal_parameter;
 import 'const_initialized_with_non_constant_value_from_deferred_library_test.dart'
     as const_initialized_with_non_constant_value_from_deferred_library;
@@ -230,6 +234,8 @@
     as inference_failure_on_collection_literal;
 import 'inference_failure_on_function_return_type_test.dart'
     as inference_failure_on_function_return_type;
+import 'inference_failure_on_instance_creation_test.dart'
+    as inference_failure_on_instance_creation;
 import 'inference_failure_on_uninitialized_variable_test.dart'
     as inference_failure_on_uninitialized_variable;
 import 'inference_failure_on_untyped_parameter_test.dart'
@@ -662,6 +668,7 @@
     conflicting_static_and_instance.main();
     conflicting_type_variable_and_container.main();
     conflicting_type_variable_and_member.main();
+    const_constructor_field_type_mismatch.main();
     const_constructor_param_type_mismatch.main();
     const_constructor_with_field_initialized_by_non_const.main();
     const_constructor_with_mixin_with_field.main();
@@ -674,6 +681,7 @@
     const_eval_type_bool_num_string.main();
     const_eval_type_bool.main();
     const_eval_type_num.main();
+    const_field_initializer_not_assignable.main();
     const_formal_parameter.main();
     const_initialized_with_non_constant_value_from_deferred_library.main();
     const_initialized_with_non_constant_value.main();
@@ -775,6 +783,7 @@
     inconsistent_language_version_override.main();
     inference_failure_on_collection_literal.main();
     inference_failure_on_function_return_type.main();
+    inference_failure_on_instance_creation.main();
     inference_failure_on_uninitialized_variable.main();
     inference_failure_on_untyped_parameter.main();
     initializer_for_non_existent_field.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
index b8e6b4c..d1daeaf 100644
--- a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -353,6 +353,19 @@
     ]);
   }
 
+  test_regression_42196_Null() async {
+    await assertNoErrorsInCode(r'''
+typedef G<X> = Function(X);
+class A<X extends G<A<X,Y>>, Y extends X> {}
+
+test<X>() { print("OK"); }
+
+main() {
+  test<A<G<A<Null, Null>>, dynamic>>();
+}
+''');
+  }
+
   test_typeArgumentList() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -435,6 +448,62 @@
 ''');
   }
 
+  test_regression_42196() async {
+    await assertNoErrorsInCode(r'''
+typedef G<X> = Function(X);
+class A<X extends G<A<X,Y>>, Y extends X> {}
+
+test<X>() { print("OK"); }
+
+main() {
+  test<A<G<A<Never, Never>>, dynamic>>();
+}
+''');
+  }
+
+  @override
+  test_regression_42196_Null() async {
+    await assertErrorsInCode(r'''
+typedef G<X> = Function(X);
+class A<X extends G<A<X,Y>>, Y extends X> {}
+
+test<X>() { print("OK"); }
+
+main() {
+  test<A<G<A<Null, Null>>, dynamic>>();
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 120, 16),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 124, 4),
+    ]);
+  }
+
+  test_regression_42196_object() async {
+    await assertNoErrorsInCode(r'''
+typedef G<X> = Function(X);
+class A<X extends G<A<X, Y>>, Y extends Never> {}
+
+test<X>() { print("OK"); }
+
+main() {
+  test<A<G<A<Never, Never>>, Object?>>();
+}
+''');
+  }
+
+  test_regression_42196_void() async {
+    await assertNoErrorsInCode(r'''
+typedef G<X> = Function(X);
+class A<X extends G<A<X, Y>>, Y extends Never> {}
+
+test<X>() { print("OK"); }
+
+main() {
+  test<A<G<A<Never, Never>>, void>>();
+}
+''');
+  }
+
   test_superBounded() async {
     await assertNoErrorsInCode(r'''
 class A<X extends A<X>> {}
diff --git a/pkg/analyzer/test/src/diagnostics/type_parameter_supertype_of_its_bound_test.dart b/pkg/analyzer/test/src/diagnostics/type_parameter_supertype_of_its_bound_test.dart
index 80d33b8..c199feb 100644
--- a/pkg/analyzer/test/src/diagnostics/type_parameter_supertype_of_its_bound_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_parameter_supertype_of_its_bound_test.dart
@@ -44,8 +44,7 @@
 }
 ''', [
       error(CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 8, 13),
-      error(
-          CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 27, 13),
+      error(CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 27, 13),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
index b7bd46a..1033aad 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
@@ -86,6 +86,13 @@
 ''');
   }
 
+  test_class_isUsed_with() async {
+    await assertNoErrorsInCode(r'''
+class _A {}
+class B with _A {}
+''');
+  }
+
   test_class_notUsed_inClassMember() async {
     await assertErrorsInCode(r'''
 class _A {
@@ -306,56 +313,6 @@
     ]);
   }
 
-  test_functionTop_isUsed_invocation() async {
-    await assertNoErrorsInCode(r'''
-_f() {}
-main() {
-  _f();
-}
-''');
-  }
-
-  test_functionTop_isUsed_reference() async {
-    await assertNoErrorsInCode(r'''
-_f() {}
-main() {
-  print(_f);
-}
-print(x) {}
-''');
-  }
-
-  test_functionTop_notUsed_noReference() async {
-    await assertErrorsInCode(r'''
-_f() {}
-main() {
-}
-''', [
-      error(HintCode.UNUSED_ELEMENT, 0, 2),
-    ]);
-  }
-
-  test_functionTop_notUsed_referenceFromItself() async {
-    await assertErrorsInCode(r'''
-_f(int p) {
-  _f(p - 1);
-}
-main() {
-}
-''', [
-      error(HintCode.UNUSED_ELEMENT, 0, 2),
-    ]);
-  }
-
-  test_functionTop_notUsed_referenceInComment() async {
-    await assertErrorsInCode(r'''
-/// [_f] is a great function.
-_f(int p) => 7;
-''', [
-      error(HintCode.UNUSED_ELEMENT, 30, 2),
-    ]);
-  }
-
   test_functionTypeAlias_isUsed_isExpression() async {
     await assertNoErrorsInCode(r'''
 typedef _F(a, b);
@@ -474,7 +431,7 @@
 ''');
   }
 
-  test_getter_isUsed_invocation_PrefixedIdentifier() async {
+  test_getter_isUsed_invocation_prefixedIdentifier() async {
     await assertErrorsInCode(r'''
 class A {
   get _g => null;
@@ -487,7 +444,7 @@
     ]);
   }
 
-  test_getter_isUsed_invocation_PropertyAccess() async {
+  test_getter_isUsed_invocation_propertyAccess() async {
     await assertErrorsInCode(r'''
 class A {
   get _g => null;
@@ -586,7 +543,7 @@
 ''');
   }
 
-  test_method_isUsed_hasReference_PrefixedIdentifier() async {
+  test_method_isUsed_hasReference_prefixedIdentifier() async {
     await assertNoErrorsInCode(r'''
 class A {
   _m() {}
@@ -597,7 +554,7 @@
 ''');
   }
 
-  test_method_isUsed_hasReference_PropertyAccess() async {
+  test_method_isUsed_hasReference_propertyAccess() async {
     await assertNoErrorsInCode(r'''
 class A {
   _m() {}
@@ -659,7 +616,7 @@
 ''');
   }
 
-  test_method_isUsed_invocation_MemberElement() async {
+  test_method_isUsed_invocation_memberElement() async {
     await assertNoErrorsInCode(r'''
 class A<T> {
   _m(T t) {}
@@ -708,16 +665,6 @@
 ''');
   }
 
-  test_method_isUsed_notPrivate() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  m() {}
-}
-main() {
-}
-''');
-  }
-
   test_method_isUsed_privateExtension() async {
     await assertNoErrorsInCode(r'''
 extension _A on String {
@@ -773,8 +720,6 @@
 ''');
   }
 
-  // Postfix operators can only be called, not defined. The "notUsed" sibling to
-  // this test is the test on a binary operator.
   test_method_isUsed_privateExtension_prefixOperator() async {
     await assertNoErrorsInCode(r'''
 extension _A on String {
@@ -786,8 +731,16 @@
 ''');
   }
 
-  // Assignment operators can only be called, not defined. The "notUsed" sibling
-  // to this test is the test on a binary operator.
+  test_method_isUsed_public() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  m() {}
+}
+main() {
+}
+''');
+  }
+
   test_method_isUsed_staticInvocation() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -855,6 +808,8 @@
     ]);
   }
 
+  // Postfix operators can only be called, not defined. The "notUsed" sibling to
+  // this test is the test on a binary operator.
   test_method_notUsed_privateExtension_indexOperator() async {
     await assertErrorsInCode(r'''
 extension _A on bool {
@@ -865,6 +820,8 @@
     ]);
   }
 
+  // Assignment operators can only be called, not defined. The "notUsed" sibling
+  // to this test is the test on a binary operator.
   test_method_notUsed_privateExtension_operator() async {
     await assertErrorsInCode(r'''
 extension _A on String {
@@ -940,6 +897,21 @@
     ]);
   }
 
+  test_mixin_isUsed_with() async {
+    await assertNoErrorsInCode(r'''
+mixin _M {}
+class C with _M {}
+''');
+  }
+
+  test_mixin_notUsed() async {
+    await assertErrorsInCode(r'''
+mixin _M {}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 6, 2),
+    ]);
+  }
+
   test_optionalParameter_constructor_named_notUsed() async {
     await assertErrorsInCode(r'''
 class A {
@@ -1341,6 +1313,56 @@
 ''');
   }
 
+  test_topLevelFunction_isUsed_invocation() async {
+    await assertNoErrorsInCode(r'''
+_f() {}
+main() {
+  _f();
+}
+''');
+  }
+
+  test_topLevelFunction_isUsed_reference() async {
+    await assertNoErrorsInCode(r'''
+_f() {}
+main() {
+  print(_f);
+}
+print(x) {}
+''');
+  }
+
+  test_topLevelFunction_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+_f() {}
+main() {
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 0, 2),
+    ]);
+  }
+
+  test_topLevelFunction_notUsed_referenceFromItself() async {
+    await assertErrorsInCode(r'''
+_f(int p) {
+  _f(p - 1);
+}
+main() {
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 0, 2),
+    ]);
+  }
+
+  test_topLevelFunction_notUsed_referenceInComment() async {
+    await assertErrorsInCode(r'''
+/// [_f] is a great function.
+_f(int p) => 7;
+''', [
+      error(HintCode.UNUSED_ELEMENT, 30, 2),
+    ]);
+  }
+
   test_topLevelVariable_isUsed() async {
     await assertNoErrorsInCode(r'''
 int _a = 1;
diff --git a/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
index 909a836..e624794 100644
--- a/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
@@ -13,10 +13,39 @@
   });
 }
 
-/// TODO(paulberry): move other tests from [CheckedModeCompileTimeErrorCodeTest]
-/// to this class.
 @reflectiveTest
 class VariableTypeMismatchTest extends DriverResolutionTest {
+  test_assignNullToInt() async {
+    await assertNoErrorsInCode('''
+const int x = null;
+''');
+  }
+
+  test_assignNullToUndefined() async {
+    await assertErrorsInCode('''
+const Unresolved x = null;
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 6, 10),
+    ]);
+  }
+
+  test_assignUnrelatedTypes() async {
+    await assertErrorsInCode('''
+const int x = 'foo';
+''', [
+      error(CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 14, 5),
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 14, 5),
+    ]);
+  }
+
+  test_assignValueToUndefined() async {
+    await assertErrorsInCode('''
+const Unresolved x = 'foo';
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 6, 10),
+    ]);
+  }
+
   test_int_to_double_variable_reference_is_not_promoted() async {
     // Note: in the following code, the declaration of `y` should produce an
     // error because we should only promote literal ints to doubles; we
@@ -25,7 +54,34 @@
 const Object x = 0;
 const double y = x;
 ''', [
-      error(CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 37, 1),
+      error(CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 37, 1),
+    ]);
+  }
+
+  test_listLiteral_inferredElementType() async {
+    await assertErrorsInCode('''
+const Object x = [1];
+const List<String> y = x;
+''', [
+      error(CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 45, 1),
+    ]);
+  }
+
+  test_mapLiteral_inferredKeyType() async {
+    await assertErrorsInCode('''
+const Object x = {1: 1};
+const Map<String, dynamic> y = x;
+''', [
+      error(CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 56, 1),
+    ]);
+  }
+
+  test_mapLiteral_inferredValueType() async {
+    await assertErrorsInCode('''
+const Object x = {1: 1};
+const Map<dynamic, String> y = x;
+''', [
+      error(CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, 56, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 34bf484..7b6be4a 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/class_hierarchy.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart';
@@ -226,5 +227,8 @@
   final ClassHierarchy classHierarchy = ClassHierarchy();
 
   @override
+  InheritanceManager3 inheritanceManager = InheritanceManager3();
+
+  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index 577c790..0139c85 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -7,11 +7,12 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/analysis/base.dart';
-import '../task/strong/strong_test_helper.dart';
+import '../dart/resolution/driver_resolution.dart';
 import 'element_text.dart';
 
 main() {
@@ -31,26 +32,24 @@
 }
 
 @reflectiveTest
-class TopLevelInferenceErrorsTest extends AbstractStrongTest {
+class TopLevelInferenceErrorsTest extends DriverResolutionTest {
   test_initializer_additive() async {
     await _assertErrorOnlyLeft(['+', '-']);
   }
 
   test_initializer_assign() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t1 = a += 1;
 var t2 = a = 2;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_binary_onlyLeft() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t = (a = 1) + (a = 2);
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_bitwise() async {
@@ -58,116 +57,107 @@
   }
 
   test_initializer_boolean() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t1 = ((a = 1) == 0) || ((a = 2) == 0);
 var t2 = ((a = 1) == 0) && ((a = 2) == 0);
 var t3 = !((a = 1) == 0);
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_cascade() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 0;
 var t = (a = 1)..isEven;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_classField_instance_instanceCreation() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 class A<T> {}
 class B {
   var t1 = new A<int>();
   var t2 = new A();
 }
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_classField_static_instanceCreation() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 class A<T> {}
 class B {
   static var t1 = 1;
   static var t2 = new A();
 }
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_conditional() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var b = true;
-var t = b ?
-          (a = 1) :
-          (a = 2);
-''';
-    await checkFile(content);
+var t = b
+    ? (a = 1)
+    : (a = 2);
+''');
   }
 
   test_initializer_dependencyCycle() async {
-    var content = r'''
-var a = /*error:TOP_LEVEL_CYCLE*/b;
-var b = /*error:TOP_LEVEL_CYCLE*/a;
-''';
-    await checkFile(content);
+    await assertErrorsInCode('''
+var a = b;
+var b = a;
+''', [
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
+    ]);
   }
 
   test_initializer_equality() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t1 = ((a = 1) == 0) == ((a = 2) == 0);
 var t2 = ((a = 1) == 0) != ((a = 2) == 0);
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_extractIndex() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = [0, 1.2];
 var b0 = a[0];
 var b1 = a[1];
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_functionLiteral_blockBody() async {
-    var content = r'''
-var t = /*error:TOP_LEVEL_FUNCTION_LITERAL_BLOCK*/
-        
-        (int p) {};
-''';
-    await checkFile(content);
+    await assertErrorsInCode('''
+var t = (int p) {};
+''', [
+      error(StrongModeCode.TOP_LEVEL_FUNCTION_LITERAL_BLOCK, 8, 10),
+    ]);
   }
 
   test_initializer_functionLiteral_expressionBody() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 0;
 var t = (int p) => (a = 1);
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_functionLiteral_parameters_withoutType() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var t = (int a, b,int c, d) => 0;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_hasTypeAnnotation() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 int t = (a = 1);
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_identifier() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 int top_function() => 0;
 var top_variable = 0;
 int get top_getter => 0;
@@ -184,67 +174,60 @@
 var t5 = A.static_getter;
 var t6 = A.static_method;
 var t7 = new A().instance_method;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_identifier_error() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 0;
 var b = (a = 1);
 var c = b;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_ifNull() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t = a ?? 2;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_instanceCreation_withoutTypeParameters() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 class A {}
 var t = new A();
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_instanceCreation_withTypeParameters() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 class A<T> {}
 var t1 = new A<int>();
 var t2 = new A();
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_instanceGetter() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 class A {
   int f = 1;
 }
 var a = new A().f;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_methodInvocation_function() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 int f1() => null;
 T f2<T>() => null;
 var t1 = f1();
 var t2 = f2();
 var t3 = f2<int>();
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_methodInvocation_method() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 class A {
   int m1() => null;
   T m2<T>() => null;
@@ -253,8 +236,7 @@
 var t1 = a.m1();
 var t2 = a.m2();
 var t3 = a.m2<int>();
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_multiplicative() async {
@@ -262,21 +244,19 @@
   }
 
   test_initializer_postfixIncDec() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t1 = a++;
 var t2 = a--;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_prefixIncDec() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t1 = ++a;
 var t2 = --a;
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_relational() async {
@@ -288,43 +268,42 @@
   }
 
   test_initializer_typedList() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t = <int>[a = 1];
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_typedMap() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t = <int, int>{(a = 1) : (a = 2)};
-''';
-    await checkFile(content);
+''');
   }
 
   test_initializer_untypedList() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t = [
-            a = 1,
-            2, 3];
-''';
-    await checkFile(content);
+    a = 1,
+    2,
+    3,
+];
+''');
   }
 
   test_initializer_untypedMap() async {
-    var content = r'''
+    await assertNoErrorsInCode('''
 var a = 1;
 var t = {
-            (a = 1) :
-            (a = 2)};
-''';
-    await checkFile(content);
+    (a = 1) :
+        (a = 2),
+};
+''');
   }
 
   test_override_conflictFieldType() async {
-    var content = r'''
+    await assertErrorsInCode('''
 abstract class A {
   int aaa;
 }
@@ -332,15 +311,16 @@
   String aaa;
 }
 class C implements A, B {
-  var /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/aaa;
+  var aaa;
 }
-''';
-    await checkFile(content);
+''', [
+      error(CompileTimeErrorCode.INVALID_OVERRIDE, 99, 3),
+      error(CompileTimeErrorCode.INVALID_OVERRIDE, 99, 3),
+    ]);
   }
 
-  @failingTest
   test_override_conflictParameterType_method() async {
-    var content = r'''
+    await assertErrorsInCode('''
 abstract class A {
   void mmm(int a);
 }
@@ -348,10 +328,11 @@
   void mmm(String a);
 }
 class C implements A, B {
-  void mmm(/*error:TOP_LEVEL_INFERENCE_ERROR*/a) {}
+  void mmm(a) {}
 }
-''';
-    await checkFile(content);
+''', [
+      error(CompileTimeErrorCode.NO_COMBINED_SUPER_SIGNATURE, 116, 3),
+    ]);
   }
 
   Future<void> _assertErrorOnlyLeft(List<String> operators) async {
@@ -360,7 +341,7 @@
       String operator = operators[i];
       code += 'var t$i = (a = 1) $operator (a = 2);\n';
     }
-    await checkFile(code);
+    await assertNoErrorsInCode(code);
   }
 }
 
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 907bbea..0ec1da6 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -11,7 +11,6 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../utils.dart';
-import '../../summary/element_text.dart';
 import 'strong_test_helper.dart';
 
 void main() {
@@ -394,29 +393,6 @@
 ''');
   }
 
-  test_constructors_inferenceFBounded() async {
-    var errors = 'error:COULD_NOT_INFER,error:COULD_NOT_INFER,'
-        'error:TYPE_ARGUMENT_NOT_MATCHING_BOUNDS';
-//    if (hasExtraTaskModelPass) errors = '$errors,$errors';
-    var unit = await checkFile('''
-class Cloneable<T> {}
-
-class Pair<T extends Cloneable<T>, U extends Cloneable<U>> {
-  T t;
-  U u;
-  Pair(this.t, this.u);
-  Pair._();
-  Pair<U, T> get reversed => new Pair(u, t);
-}
-
-main() {
-  final x = new /*$errors*/Pair._();
-}
-''');
-    var x = findLocalVariable(unit, 'x');
-    _assertTypeStr(x.type, 'Pair<Cloneable<dynamic>, Cloneable<dynamic>>');
-  }
-
   test_constructors_inferFromArguments() async {
     var unit = await checkFile('''
 class C<T> {
@@ -446,28 +422,6 @@
     _assertTypeStr(findLocalVariable(unit, 'c_dynamic').type, 'C<dynamic>');
   }
 
-  test_constructors_inferFromArguments_argumentNotAssignable() async {
-    var unit = await checkFile('''
-class A {}
-
-typedef T F<T>();
-
-class C<T extends A> {
-  C(F<T> f);
-}
-
-class NotA {}
-NotA myF() => null;
-
-main() {
-  var x = new
-      /*error:COULD_NOT_INFER,error:TYPE_ARGUMENT_NOT_MATCHING_BOUNDS*/C(myF);
-}
-''');
-    var x = findLocalVariable(unit, 'x');
-    _assertTypeStr(x.type, 'C<NotA>');
-  }
-
   test_constructors_inferFromArguments_const() async {
     var unit = await checkFile('''
 class C<T> {
@@ -714,21 +668,6 @@
 ''');
   }
 
-  test_downwardInference_fixes_noUpwardsErrors() async {
-    await checkFileElement(r'''
-import 'dart:math';
-// T max<T extends num>(T x, T y);
-main() {
-  num x;
-  dynamic y;
-
-  num a = max(x, y);
-  Object b = max(x, y);
-  dynamic c = /*error:COULD_NOT_INFER*/max(x, y);
-  var d = /*error:COULD_NOT_INFER*/max(x, y);
-}''');
-  }
-
   test_downwardInference_miscellaneous() async {
     await checkFileElement('''
 typedef T Function2<S, T>(S x);
@@ -1739,18 +1678,6 @@
 ''');
   }
 
-  test_genericMethods_correctlyRecognizeGenericUpperBound() async {
-    // Regression test for https://github.com/dart-lang/sdk/issues/25740.
-    await checkFileElement(r'''
-class Foo<T extends Pattern> {
-  U method<U extends T>(U u) => u;
-}
-main() {
-  new Foo<String>()./*error:COULD_NOT_INFER*/method(42);
-}
-''');
-  }
-
   test_genericMethods_dartMathMinMax() async {
     await checkFileElement('''
 import 'dart:math';
@@ -1901,100 +1828,6 @@
     _assertTypeStr(f.type, 'U Function() Function<U>(U)');
   }
 
-  test_genericMethods_inferGenericInstantiation() async {
-    await checkFileElement('''
-import 'dart:math' as math;
-import 'dart:math' show min;
-
-class C {
-T m<T extends num>(T x, T y) => null;
-}
-
-main() {
-takeIII(math.max);
-takeDDD(math.max);
-takeNNN(math.max);
-takeIDN(math.max);
-takeDIN(math.max);
-takeIIN(math.max);
-takeDDN(math.max);
-takeIIO(math.max);
-takeDDO(math.max);
-
-takeOOI(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/math.max);
-takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
-takeOON(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/math.max);
-takeOOO(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/math.max);
-
-// Also test SimpleIdentifier
-takeIII(min);
-takeDDD(min);
-takeNNN(min);
-takeIDN(min);
-takeDIN(min);
-takeIIN(min);
-takeDDN(min);
-takeIIO(min);
-takeDDO(min);
-
-takeOOI(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/min);
-takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
-takeOON(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/min);
-takeOOO(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/min);
-
-// Also PropertyAccess
-takeIII(new C().m);
-takeDDD(new C().m);
-takeNNN(new C().m);
-takeIDN(new C().m);
-takeDIN(new C().m);
-takeIIN(new C().m);
-takeDDN(new C().m);
-takeIIO(new C().m);
-takeDDO(new C().m);
-
-// Note: this is a warning because a downcast of a method tear-off could work
-// (derived method can be a subtype):
-//
-//     class D extends C {
-//       S m<S extends num>(Object x, Object y);
-//     }
-//
-// That's legal because we're loosening parameter types.
-//
-// We do issue the inference error though, similar to generic function calls.
-takeOON(/*error:COULD_NOT_INFER*/new C().m);
-takeOOO(/*error:COULD_NOT_INFER*/new C().m);
-
-// Note: this is a warning because a downcast of a method tear-off could work
-// in "normal" Dart, due to bivariance.
-//
-// We do issue the inference error though, similar to generic function calls.
-takeOOI(/*error:COULD_NOT_INFER*/new C().m);
-
-takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
-}
-
-void takeIII(int fn(int a, int b)) {}
-void takeDDD(double fn(double a, double b)) {}
-void takeIDI(int fn(double a, int b)) {}
-void takeDID(double fn(int a, double b)) {}
-void takeIDN(num fn(double a, int b)) {}
-void takeDIN(num fn(int a, double b)) {}
-void takeIIN(num fn(int a, int b)) {}
-void takeDDN(num fn(double a, double b)) {}
-void takeNNN(num fn(num a, num b)) {}
-void takeOON(num fn(Object a, Object b)) {}
-void takeOOO(num fn(Object a, Object b)) {}
-void takeOOI(int fn(Object a, Object b)) {}
-void takeIIO(Object fn(int a, int b)) {}
-void takeDDO(Object fn(double a, double b)) {}
-''');
-  }
-
   test_genericMethods_inferGenericMethodType() async {
     // Regression test for https://github.com/dart-lang/sdk/issues/25668
     await checkFileElement('''
@@ -3391,151 +3224,6 @@
     _assertTypeStr(x.type, 'void');
   }
 
-  test_instantiateToBounds_invokeConstructor_noBound() async {
-    var unit = await checkFileElement('''
-class C<T> {}
-var x = new C();
-''');
-    _assertTypeStr(unit.topLevelVariables[0].type, 'C<dynamic>');
-  }
-
-  test_instantiateToBounds_invokeConstructor_typeArgsExact() async {
-    var unit = await checkFileElement('''
-class C<T extends num> {}
-var x = new C<int>();
-''');
-    _assertTypeStr(unit.topLevelVariables[0].type, 'C<int>');
-  }
-
-  test_instantiateToBounds_notGeneric() async {
-    var unit = await checkFileElement(r'''
-class A {}
-class B<T extends A> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-class A {
-}
-class B<T extends A> {
-}
-B<A> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_error1() async {
-    var unit = await checkFileElement(r'''
-class A<T1 extends int, T2 extends T1> {}
-class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-notSimplyBounded class A<T1 extends int, T2 extends T1> {
-}
-notSimplyBounded class B<T extends A<int, int>> {
-}
-B<A<int, int>> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_error2() async {
-    var unit = await checkFileElement(r'''
-class A<T1 extends T2, T2 extends int> {}
-class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-notSimplyBounded class A<T1 extends T2, T2 extends int> {
-}
-notSimplyBounded class B<T extends A<int, int>> {
-}
-B<A<int, int>> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_error3() async {
-    var unit = await checkFileElement(r'''
-class A<T1 extends int, T2 extends List<T1>> {}
-class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-notSimplyBounded class A<T1 extends int, T2 extends List<T1>> {
-}
-notSimplyBounded class B<T extends A<int, List<int>>> {
-}
-B<A<int, List<int>>> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_OK_hasBound_definedAfter() async {
-    var unit = await checkFileElement(r'''
-class B<T extends A> {}
-class A<T extends int> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-class B<T extends A<int>> {
-}
-class A<T extends int> {
-}
-B<A<int>> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_OK_hasBound_definedBefore() async {
-    var unit = await checkFileElement(r'''
-class A<T extends int> {}
-class B<T extends A> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-class A<T extends int> {
-}
-class B<T extends A<int>> {
-}
-B<A<int>> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_OK_inBound_hasBound_definedAfter() async {
-    var unit = await checkFileElement(r'''
-A v = null;
-class A<T extends int> {}
-''');
-    checkElementText(unit.library, r'''
-class A<T extends int> {
-}
-A<int> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_OK_inBound_hasBound_definedBefore() async {
-    var unit = await checkFileElement(r'''
-class A<T extends int> {}
-A v = null;
-''');
-    checkElementText(unit.library, r'''
-class A<T extends int> {
-}
-A<int> v;
-''');
-  }
-
-  test_instantiateToBounds_typeName_OK_noBound() async {
-    var unit = await checkFileElement(r'''
-class A<T> {}
-class B<T extends A> {}
-B v = null;
-''');
-    checkElementText(unit.library, r'''
-class A<T> {
-}
-class B<T extends A<dynamic>> {
-}
-B<A<dynamic>> v;
-''');
-  }
-
   test_lambdaDoesNotHavePropagatedTypeHint() async {
     await checkFileElement(r'''
 List<String> getListOfString() => const <String>[];
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index d60de7c..945b34c 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -806,6 +806,9 @@
   /// Entry point to the code generator when generating the "format.dart" file.
   void generateFormatCode() {
     outputHeader();
+    out("// The generator sometimes generates unnecessary 'this' references.");
+    out('// ignore_for_file: unnecessary_this');
+    out();
     out('library analyzer.src.summary.format;');
     out();
     out("import 'dart:convert' as convert;");
@@ -848,7 +851,7 @@
     out('// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file');
     out('// for details. All rights reserved. Use of this source code is governed by a');
     out('// BSD-style license that can be found in the LICENSE file.');
-    out('//');
+    out();
     out('// This file has been automatically generated.  Please do not edit it manually.');
     out('// To regenerate the file, use the SDK script');
     out('// "pkg/analyzer/tool/summary/generate.dart \$IDL_FILE_PATH",');
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 57b4ef2..7bdcc3b 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -112,8 +112,8 @@
         }
 
         // Prepare options.
-        var options =
-            CommandLineOptions.parse(arguments, printAndFail: (String msg) {
+        var options = CommandLineOptions.parse(resourceProvider, arguments,
+            printAndFail: (String msg) {
           throw ArgumentError(msg);
         });
 
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 9a619af..de97117 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -126,7 +126,7 @@
     linter.registerLintRules();
 
     // Parse commandline options.
-    var options = CommandLineOptions.parse(args);
+    var options = CommandLineOptions.parse(resourceProvider, args);
 
     // Do analysis.
     if (options.buildMode) {
@@ -140,7 +140,7 @@
       batchRunner.runAsBatch(args, (List<String> args) async {
         // TODO(brianwilkerson) Determine whether this await is necessary.
         await null;
-        var options = CommandLineOptions.parse(args);
+        var options = CommandLineOptions.parse(resourceProvider, args);
         return await _analyzeAll(options);
       });
     } else {
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index b4314f9..59bbd3f 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -2,8 +2,9 @@
 // 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 'dart:io';
+import 'dart:io' as io;
 
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
@@ -18,7 +19,7 @@
 /// Shared exit handler.
 ///
 /// *Visible for testing.*
-ExitHandler exitHandler = exit;
+ExitHandler exitHandler = io.exit;
 
 T cast<T>(dynamic value) => value as T;
 
@@ -151,8 +152,10 @@
   final String summaryDepsOutput;
 
   /// Initialize options from the given parsed [args].
-  CommandLineOptions._fromArgs(ArgResults args)
-      : buildAnalysisOutput = cast(args['build-analysis-output']),
+  CommandLineOptions._fromArgs(
+    ResourceProvider resourceProvider,
+    ArgResults args,
+  )   : buildAnalysisOutput = cast(args['build-analysis-output']),
         buildMode = cast(args['build-mode']),
         buildModePersistentWorker = cast(args['persistent_worker']),
         buildSummaryInputs =
@@ -162,7 +165,10 @@
         buildSummaryOutputSemantic =
             cast(args['build-summary-output-semantic']),
         buildSuppressExitCode = cast(args['build-suppress-exit-code']),
-        contextBuilderOptions = createContextBuilderOptions(args),
+        contextBuilderOptions = createContextBuilderOptions(
+          resourceProvider,
+          args,
+        ),
         dartSdkPath = cast(args['dart-sdk']),
         dartSdkSummaryPath = cast(args['dart-sdk-summary']),
         defaultLanguageVersion = cast(args['default-language-version']),
@@ -214,9 +220,10 @@
   /// Parse [args] into [CommandLineOptions] describing the specified
   /// analyzer options. In case of a format error, calls [printAndFail], which
   /// by default prints an error message to stderr and exits.
-  static CommandLineOptions parse(List<String> args,
+  static CommandLineOptions parse(
+      ResourceProvider resourceProvider, List<String> args,
       {void Function(String msg) printAndFail = printAndFail}) {
-    var options = _parse(args);
+    var options = _parse(resourceProvider, args);
 
     /// Only happens in testing.
     if (options == null) {
@@ -236,7 +243,7 @@
         return null; // Only reachable in testing.
       }
       // Check that SDK is existing directory.
-      if (!(Directory(sdkPath)).existsSync()) {
+      if (!(io.Directory(sdkPath)).existsSync()) {
         printAndFail('Invalid Dart SDK path: $sdkPath');
         return null; // Only reachable in testing.
       }
@@ -271,8 +278,9 @@
   static String _getVersion() {
     try {
       // This is relative to bin/snapshot, so ../..
-      var versionPath = Platform.script.resolve('../../version').toFilePath();
-      var versionFile = File(versionPath);
+      var versionPath =
+          io.Platform.script.resolve('../../version').toFilePath();
+      var versionFile = io.File(versionPath);
       return versionFile.readAsStringSync().trim();
     } catch (_) {
       // This happens when the script is not running in the context of an SDK.
@@ -280,7 +288,10 @@
     }
   }
 
-  static CommandLineOptions _parse(List<String> args) {
+  static CommandLineOptions _parse(
+    ResourceProvider resourceProvider,
+    List<String> args,
+  ) {
     args = preprocessArgs(PhysicalResourceProvider.INSTANCE, args);
 
     var verbose = args.contains('-v') || args.contains('--verbose');
@@ -504,7 +515,7 @@
               'option. Got: $args');
           return null; // Only reachable in testing.
         }
-        return CommandLineOptions._fromArgs(results);
+        return CommandLineOptions._fromArgs(resourceProvider, results);
       }
 
       // Help requests.
@@ -565,7 +576,7 @@
         }
       }
 
-      return CommandLineOptions._fromArgs(results);
+      return CommandLineOptions._fromArgs(resourceProvider, results);
     } on FormatException catch (e) {
       errorSink.writeln(e.message);
       _showUsage(parser);
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 573233a..9d682ef 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io';
 
+import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/experiments_impl.dart'
     show overrideKnownFeatures;
@@ -22,6 +23,13 @@
       int savedExitCode;
       ExitHandler savedExitHandler;
 
+      CommandLineOptions parse(List<String> args,
+          {void Function(String msg) printAndFail = printAndFail}) {
+        var resourceProvider = PhysicalResourceProvider.INSTANCE;
+        return CommandLineOptions.parse(resourceProvider, args,
+            printAndFail: printAndFail);
+      }
+
       setUp(() {
         savedOutSink = outSink;
         savedErrorSink = errorSink;
@@ -40,7 +48,7 @@
       });
 
       test('defaults', () {
-        var options = CommandLineOptions.parse(['--dart-sdk', '.', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', 'foo.dart']);
         expect(options, isNotNull);
         expect(options.buildMode, isFalse);
         expect(options.buildAnalysisOutput, isNull);
@@ -70,20 +78,19 @@
       });
 
       test('batch', () {
-        var options = CommandLineOptions.parse(['--dart-sdk', '.', '--batch']);
+        var options = parse(['--dart-sdk', '.', '--batch']);
         expect(options.batchMode, isTrue);
       });
 
       test('defined variables', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart']);
         expect(options.definedVariables['foo'], equals('bar'));
         expect(options.definedVariables['bar'], isNull);
       });
 
       test('disable cache flushing', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart']);
+        var options =
+            parse(['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart']);
         expect(options.disableCacheFlushing, isTrue);
       });
 
@@ -116,32 +123,28 @@
         };
 
         test('no values', () {
-          var options = overrideKnownFeatures(
-              knownFeatures, () => CommandLineOptions.parse(['foo.dart']));
+          var options =
+              overrideKnownFeatures(knownFeatures, () => parse(['foo.dart']));
           expect(options.enabledExperiments, isEmpty);
         });
 
         test('single value', () {
-          var options = overrideKnownFeatures(
-              knownFeatures,
-              () => CommandLineOptions.parse(
-                  ['--enable-experiment', 'a', 'foo.dart']));
+          var options = overrideKnownFeatures(knownFeatures,
+              () => parse(['--enable-experiment', 'a', 'foo.dart']));
           expect(options.enabledExperiments, ['a']);
         });
 
         group('multiple values', () {
           test('single flag', () {
-            var options = overrideKnownFeatures(
-                knownFeatures,
-                () => CommandLineOptions.parse(
-                    ['--enable-experiment', 'a,b', 'foo.dart']));
+            var options = overrideKnownFeatures(knownFeatures,
+                () => parse(['--enable-experiment', 'a,b', 'foo.dart']));
             expect(options.enabledExperiments, ['a', 'b']);
           });
 
           test('mixed single and multiple flags', () {
             var options = overrideKnownFeatures(
                 knownFeatures,
-                () => CommandLineOptions.parse([
+                () => parse([
                       '--enable-experiment',
                       'a,b',
                       '--enable-experiment',
@@ -154,7 +157,7 @@
           test('multiple flags', () {
             var options = overrideKnownFeatures(
                 knownFeatures,
-                () => CommandLineOptions.parse([
+                () => parse([
                       '--enable-experiment',
                       'a',
                       '--enable-experiment',
@@ -167,74 +170,68 @@
       });
 
       test('hintsAreFatal', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
         expect(options.infosAreFatal, isTrue);
       });
 
       test('infosAreFatal', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--fatal-infos', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--fatal-infos', 'foo.dart']);
         expect(options.infosAreFatal, isTrue);
       });
 
       test('log', () {
-        var options =
-            CommandLineOptions.parse(['--dart-sdk', '.', '--log', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--log', 'foo.dart']);
         expect(options.log, isTrue);
       });
 
       test('machine format', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--format=machine', 'foo.dart']);
+        var options =
+            parse(['--dart-sdk', '.', '--format=machine', 'foo.dart']);
         expect(options.machineFormat, isTrue);
       });
 
       test('no-hints', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--no-hints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--no-hints', 'foo.dart']);
         expect(options.disableHints, isTrue);
       });
 
       test('options', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart']);
-        expect(options.analysisOptionsFile, equals('options.yaml'));
+        var options =
+            parse(['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart']);
+        expect(options.analysisOptionsFile, endsWith('options.yaml'));
       });
 
       test('lints', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--lints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--lints', 'foo.dart']);
         expect(options.lints, isTrue);
       });
 
       test('package warnings', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
+        var options =
+            parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
         expect(options.showPackageWarnings, isTrue);
       });
 
       test('sdk warnings', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--sdk-warnings', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--sdk-warnings', 'foo.dart']);
         expect(options.showSdkWarnings, isTrue);
       });
 
       test('sourceFiles', () {
-        var options = CommandLineOptions.parse(
+        var options = parse(
             ['--dart-sdk', '.', '--log', 'foo.dart', 'foo2.dart', 'foo3.dart']);
         expect(options.sourceFiles,
             equals(['foo.dart', 'foo2.dart', 'foo3.dart']));
       });
 
       test('warningsAreFatal', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--fatal-warnings', 'foo.dart']);
+        var options =
+            parse(['--dart-sdk', '.', '--fatal-warnings', 'foo.dart']);
         expect(options.warningsAreFatal, isTrue);
       });
 
       test('ignore unrecognized flags', () {
-        var options = CommandLineOptions.parse([
+        var options = parse([
           '--ignore-unrecognized-flags',
           '--bar',
           '--baz',
@@ -247,27 +244,24 @@
       });
 
       test('hintsAreFatal', () {
-        var options = CommandLineOptions.parse(
-            ['--dart-sdk', '.', '--fatal-lints', 'foo.dart']);
+        var options = parse(['--dart-sdk', '.', '--fatal-lints', 'foo.dart']);
         expect(options.lintsAreFatal, isTrue);
       });
 
       test('bad SDK dir', () {
         String failureMessage;
-        CommandLineOptions.parse(['--dart-sdk', '&&&&&', 'foo.dart'],
+        parse(['--dart-sdk', '&&&&&', 'foo.dart'],
             printAndFail: (msg) => failureMessage = msg);
         expect(failureMessage, equals('Invalid Dart SDK path: &&&&&'));
       });
 
       test('--use-fasta-parser', () {
-        var options =
-            CommandLineOptions.parse(['--use-fasta-parser', 'foo.dart']);
+        var options = parse(['--use-fasta-parser', 'foo.dart']);
         expect(options.useFastaParser, isTrue);
       });
 
       test('--train-snapshot', () {
-        var options =
-            CommandLineOptions.parse(['--train-snapshot', 'foo.dart']);
+        var options = parse(['--train-snapshot', 'foo.dart']);
         expect(options.trainSnapshot, isTrue);
       });
     });
@@ -421,7 +415,9 @@
   }
 
   void _parse(List<String> args) {
-    options = CommandLineOptions.parse(args, printAndFail: (msg) {
+    var resourceProvider = PhysicalResourceProvider.INSTANCE;
+    options =
+        CommandLineOptions.parse(resourceProvider, args, printAndFail: (msg) {
       failureMessage = msg;
     });
   }
diff --git a/pkg/analyzer_cli/test/perf_report_test.dart b/pkg/analyzer_cli/test/perf_report_test.dart
index c75d94a..933b455 100644
--- a/pkg/analyzer_cli/test/perf_report_test.dart
+++ b/pkg/analyzer_cli/test/perf_report_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:convert' show json;
 
+import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer_cli/src/error_formatter.dart' show AnalysisStats;
 import 'package:analyzer_cli/src/options.dart';
 import 'package:analyzer_cli/src/perf_report.dart';
@@ -11,7 +12,10 @@
 
 void main() {
   test('makePerfReport', () {
-    var options = CommandLineOptions.parse(['somefile.dart']);
+    var options = CommandLineOptions.parse(
+      PhysicalResourceProvider.INSTANCE,
+      ['somefile.dart'],
+    );
     var encoded = makePerfReport(1000, 1234, options, 0, AnalysisStats());
 
     var jsonData = json.decode(encoded);
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index d508b6b..9e116f8 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -22,6 +22,7 @@
   static const String enableAssertMessage = '--assert-message';
   static const String enableCheckedMode = '--enable-checked-mode';
   static const String enableAsserts = '--enable-asserts';
+  static const String enableNullAssertions = '--null-assertions';
   static const String enableDiagnosticColors = '--enable-diagnostic-colors';
   static const String experimentalTrackAllocations =
       '--experimental-track-allocations';
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 5bb3660..54828f1 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -28,6 +28,7 @@
 import 'frontend_strategy.dart';
 import 'inferrer/abstract_value_domain.dart' show AbstractValueStrategy;
 import 'inferrer/trivial.dart' show TrivialAbstractValueStrategy;
+import 'inferrer/powersets/wrapped.dart' show WrappedAbstractValueStrategy;
 import 'inferrer/typemasks/masks.dart' show TypeMaskStrategy;
 import 'inferrer/types.dart'
     show GlobalTypeInferenceResults, GlobalTypeInferenceTask;
@@ -135,11 +136,14 @@
     options.deriveOptions();
     options.validate();
 
-    abstractValueStrategy = options.experimentalPowersets
-        ? throw UnimplementedError('Powerset abstract value domain')
-        : options.useTrivialAbstractValueDomain
-            ? const TrivialAbstractValueStrategy()
-            : const TypeMaskStrategy();
+    abstractValueStrategy = options.useTrivialAbstractValueDomain
+        ? const TrivialAbstractValueStrategy()
+        : const TypeMaskStrategy();
+    if (options.experimentalPowersets) {
+      abstractValueStrategy =
+          WrappedAbstractValueStrategy(abstractValueStrategy);
+    }
+
     CompilerTask kernelFrontEndTask;
     selfTask = new GenericTask('self', measurer);
     _outputProvider = new _CompilerOutput(this, outputProvider);
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index ebeac09..14b1867 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -9,7 +9,6 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../deferred_load.dart' show OutputUnit;
-import '../inferrer/abstract_value_domain.dart';
 import '../js/js.dart' as js;
 import '../util/util.dart';
 
@@ -862,26 +861,19 @@
   String toStructuredText(DartTypes dartTypes) => 'JsNameConstant(${name})';
 }
 
-/// A constant used as the dummy interceptor value for intercepted calls with
+/// A constant used as the dummy receiver value for intercepted calls with
 /// a known non-interceptor target.
+// TODO(sra): Rename fo 'DummyReceiverConstantValue'.
 class DummyInterceptorConstantValue extends ConstantValue {
-  final AbstractValue abstractValue;
+  factory DummyInterceptorConstantValue() =>
+      const DummyInterceptorConstantValue._();
 
-  DummyInterceptorConstantValue(this.abstractValue);
+  const DummyInterceptorConstantValue._();
 
   @override
   bool get isDummy => true;
 
   @override
-  bool operator ==(other) {
-    return other is DummyInterceptorConstantValue &&
-        abstractValue == other.abstractValue;
-  }
-
-  @override
-  get hashCode => abstractValue.hashCode * 17;
-
-  @override
   List<ConstantValue> getDependencies() => const <ConstantValue>[];
 
   @override
@@ -896,11 +888,10 @@
   ConstantValueKind get kind => ConstantValueKind.DUMMY_INTERCEPTOR;
 
   @override
-  String toDartText(DartTypes dartTypes) => 'dummy_interceptor($abstractValue)';
+  String toDartText(DartTypes dartTypes) => 'dummy_interceptor()';
 
   @override
-  String toStructuredText(DartTypes dartTypes) =>
-      'DummyInterceptorConstant($abstractValue)';
+  String toStructuredText(DartTypes dartTypes) => 'DummyInterceptorConstant()';
 }
 
 // A constant with an empty type used in [HInstruction]s of an expression
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index ac41334..32c3b63 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -429,6 +429,7 @@
     new OptionHandler('--enable[_-]checked[_-]mode|--checked',
         (_) => setCheckedMode(Flags.enableCheckedMode)),
     new OptionHandler(Flags.enableAsserts, passThrough),
+    new OptionHandler(Flags.enableNullAssertions, passThrough),
     new OptionHandler(Flags.trustTypeAnnotations, setTrustTypeAnnotations),
     new OptionHandler(Flags.trustPrimitives, passThrough),
     new OptionHandler(Flags.trustJSInteropTypeAnnotations, passThrough),
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index e7fa6cd..97c7256 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -353,6 +353,7 @@
             case TypeUseKind.RTI_VALUE:
             case TypeUseKind.TYPE_ARGUMENT:
             case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
+            case TypeUseKind.CONSTRUCTOR_REFERENCE:
               failedAt(element, "Unexpected type use: $typeUse.");
               break;
           }
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index db613ff..151df1e 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -197,27 +197,6 @@
               """
           ]),
 
-      MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
-          const MessageTemplate(
-              MessageKind
-                  .JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
-              "Some parameters in anonymous js-interop class '#{cls}' "
-              "object literal constructor are positional instead of named."
-              ".",
-              howToFix: "Make all arguments in external factory object literal "
-                  "constructors named.",
-              examples: const [
-            """
-class Super {
-  factory Super.foo() => null;
-}
-class Class extends Super {
-  Class() : super.foo();
-}
-main() => new Class();
-"""
-          ]),
-
       MessageKind.JS_INTEROP_NON_EXTERNAL_MEMBER: const MessageTemplate(
           MessageKind.JS_INTEROP_NON_EXTERNAL_MEMBER,
           "Js-interop members must be 'external'."),
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 00dd891..2b45419 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -2303,4 +2303,32 @@
             canAssignGenericFunctionTo(getTypeVariableBound(type.element)) ||
         type is FunctionTypeVariable && canAssignGenericFunctionTo(type.bound);
   }
+
+  /// Returns `true` if [type] occuring in a program with no sound null safety
+  /// cannot accept `null` under sound rules.
+  bool isNonNullableIfSound(DartType type) {
+    if (type is DynamicType ||
+        type is VoidType ||
+        type is AnyType ||
+        type is ErasedType) {
+      return false;
+    }
+    if (type is NullableType) return false;
+    if (type is LegacyType) {
+      return isNonNullableIfSound(type.baseType);
+    }
+    if (type is InterfaceType) {
+      if (type.isNull) return false;
+      return true;
+    }
+    if (type is FunctionType) return true;
+    if (type is NeverType) return true;
+    if (type is TypeVariableType) {
+      return isNonNullableIfSound(getTypeVariableBound(type.element));
+    }
+    if (type is FutureOrType) {
+      return isNonNullableIfSound(type.typeArgument);
+    }
+    throw UnimplementedError('isNonNullableIfSound $type');
+  }
 }
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index feda38d..c3c07e6 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -416,6 +416,7 @@
         break;
       case TypeUseKind.RTI_VALUE:
       case TypeUseKind.TYPE_ARGUMENT:
+      case TypeUseKind.CONSTRUCTOR_REFERENCE:
         failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
         break;
       case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
diff --git a/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart b/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart
new file mode 100644
index 0000000..c30f196
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/powersets/wrapped.dart
@@ -0,0 +1,653 @@
+// Copyright (c) 2018, 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 '../../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
+import '../../elements/entities.dart';
+import '../../elements/names.dart';
+import '../../elements/types.dart' show DartType;
+import '../../ir/static_type.dart';
+import '../../serialization/serialization.dart';
+import '../../universe/selector.dart';
+import '../../universe/world_builder.dart';
+import '../../universe/use.dart';
+import '../../world.dart';
+import '../abstract_value_domain.dart';
+
+class WrappedAbstractValue implements AbstractValue {
+  final AbstractValue _abstractValue;
+  const WrappedAbstractValue(this._abstractValue);
+
+  @override
+  bool operator ==(var other) {
+    if (identical(this, other)) return true;
+    if (other is! WrappedAbstractValue) return false;
+    WrappedAbstractValue otherWrapped = other;
+    return other is WrappedAbstractValue &&
+        _abstractValue == otherWrapped._abstractValue;
+  }
+
+  @override
+  int get hashCode {
+    return _abstractValue.hashCode;
+  }
+
+  @override
+  String toString() => _abstractValue.toString();
+}
+
+AbstractValue unwrapOrNull(WrappedAbstractValue wrapped) {
+  return wrapped == null ? null : wrapped._abstractValue;
+}
+
+WrappedAbstractValue wrapOrNull(AbstractValue abstractValue) {
+  return abstractValue == null ? null : WrappedAbstractValue(abstractValue);
+}
+
+class WrappedAbstractValueDomain implements AbstractValueDomain {
+  final AbstractValueDomain _abstractValueDomain;
+  const WrappedAbstractValueDomain(this._abstractValueDomain);
+
+  @override
+  AbstractValue get dynamicType =>
+      WrappedAbstractValue(_abstractValueDomain.dynamicType);
+
+  @override
+  void writeAbstractValueToDataSink(
+      DataSink sink, covariant WrappedAbstractValue value) {
+    _abstractValueDomain.writeAbstractValueToDataSink(
+        sink, value._abstractValue);
+  }
+
+  @override
+  AbstractValue readAbstractValueFromDataSource(DataSource source) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.readAbstractValueFromDataSource(source));
+
+  @override
+  String getCompactText(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getCompactText(value._abstractValue);
+
+  @override
+  AbstractBool isFixedLengthJsIndexable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isFixedLengthJsIndexable(value._abstractValue);
+
+  @override
+  AbstractBool isJsIndexableAndIterable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isJsIndexableAndIterable(unwrapOrNull(value));
+
+  @override
+  AbstractBool isJsIndexable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isJsIndexable(value._abstractValue);
+
+  @override
+  MemberEntity locateSingleMember(
+          covariant WrappedAbstractValue receiver, Selector selector) =>
+      _abstractValueDomain.locateSingleMember(
+          receiver._abstractValue, selector);
+
+  @override
+  AbstractBool isIn(covariant WrappedAbstractValue subset,
+          covariant WrappedAbstractValue superset) =>
+      _abstractValueDomain.isIn(subset._abstractValue, superset._abstractValue);
+
+  @override
+  AbstractBool needsNoSuchMethodHandling(
+          covariant WrappedAbstractValue receiver, Selector selector) =>
+      _abstractValueDomain.needsNoSuchMethodHandling(
+          receiver._abstractValue, selector);
+
+  @override
+  AbstractBool isTargetingMember(covariant WrappedAbstractValue receiver,
+          MemberEntity member, Name name) =>
+      _abstractValueDomain.isTargetingMember(
+          receiver._abstractValue, member, name);
+
+  @override
+  AbstractValue computeReceiver(Iterable<MemberEntity> members) =>
+      WrappedAbstractValue(_abstractValueDomain.computeReceiver(members));
+
+  @override
+  PrimitiveConstantValue getPrimitiveValue(
+          covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getPrimitiveValue(value._abstractValue);
+
+  @override
+  AbstractValue createPrimitiveValue(
+          covariant WrappedAbstractValue originalValue,
+          PrimitiveConstantValue value) =>
+      WrappedAbstractValue(_abstractValueDomain.createPrimitiveValue(
+          originalValue._abstractValue, value));
+
+  @override
+  bool isPrimitiveValue(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveValue(value._abstractValue);
+
+  @override
+  MemberEntity getAllocationElement(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getAllocationElement(value._abstractValue);
+
+  @override
+  Object getAllocationNode(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getAllocationNode(value._abstractValue);
+
+  @override
+  AbstractValue getGeneralization(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getGeneralization(unwrapOrNull(value)));
+
+  @override
+  bool isSpecializationOf(covariant WrappedAbstractValue specialization,
+          covariant WrappedAbstractValue generalization) =>
+      _abstractValueDomain.isSpecializationOf(
+          specialization._abstractValue, generalization._abstractValue);
+
+  @override
+  AbstractValue getDictionaryValueForKey(
+          covariant WrappedAbstractValue value, String key) =>
+      WrappedAbstractValue(_abstractValueDomain.getDictionaryValueForKey(
+          value._abstractValue, key));
+
+  @override
+  bool containsDictionaryKey(
+          covariant WrappedAbstractValue value, String key) =>
+      _abstractValueDomain.containsDictionaryKey(value._abstractValue, key);
+
+  @override
+  AbstractValue createDictionaryValue(
+      covariant WrappedAbstractValue originalValue,
+      Object allocationNode,
+      MemberEntity allocationElement,
+      covariant WrappedAbstractValue key,
+      covariant WrappedAbstractValue value,
+      covariant Map<String, AbstractValue> mappings) {
+    return WrappedAbstractValue(_abstractValueDomain.createDictionaryValue(
+        originalValue._abstractValue,
+        allocationNode,
+        allocationElement,
+        key._abstractValue,
+        value._abstractValue, {
+      for (var entry in mappings.entries)
+        entry.key: (entry.value as WrappedAbstractValue)._abstractValue
+    }));
+  }
+
+  @override
+  bool isDictionary(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isDictionary(value._abstractValue);
+
+  @override
+  AbstractValue getMapValueType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getMapValueType(value._abstractValue));
+
+  @override
+  AbstractValue getMapKeyType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getMapKeyType(value._abstractValue));
+
+  @override
+  AbstractValue createMapValue(
+          covariant WrappedAbstractValue originalValue,
+          Object allocationNode,
+          MemberEntity allocationElement,
+          covariant WrappedAbstractValue key,
+          covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(_abstractValueDomain.createMapValue(
+          originalValue._abstractValue,
+          allocationNode,
+          allocationElement,
+          key._abstractValue,
+          value._abstractValue));
+
+  @override
+  bool isMap(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isMap(value._abstractValue);
+
+  @override
+  AbstractValue getSetElementType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getSetElementType(value._abstractValue));
+
+  @override
+  AbstractValue createSetValue(
+          covariant WrappedAbstractValue originalValue,
+          Object allocationNode,
+          MemberEntity allocationElement,
+          covariant WrappedAbstractValue elementType) =>
+      WrappedAbstractValue(_abstractValueDomain.createSetValue(
+          originalValue._abstractValue,
+          allocationNode,
+          allocationElement,
+          elementType._abstractValue));
+
+  @override
+  bool isSet(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isSet(value._abstractValue);
+
+  @override
+  int getContainerLength(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getContainerLength(value._abstractValue);
+
+  @override
+  AbstractValue getContainerElementType(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.getContainerElementType(value._abstractValue));
+
+  @override
+  AbstractValue createContainerValue(
+          covariant WrappedAbstractValue originalValue,
+          Object allocationNode,
+          MemberEntity allocationElement,
+          covariant WrappedAbstractValue elementType,
+          int length) =>
+      WrappedAbstractValue(_abstractValueDomain.createContainerValue(
+          originalValue._abstractValue,
+          allocationNode,
+          allocationElement,
+          elementType._abstractValue,
+          length));
+
+  @override
+  bool isContainer(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isContainer(value._abstractValue);
+
+  @override
+  AbstractValue computeAbstractValueForConstant(
+          covariant ConstantValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.computeAbstractValueForConstant(value));
+
+  @override
+  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) {
+    return wrapOrNull(_abstractValueDomain
+        .getAbstractValueForNativeMethodParameterType(type));
+  }
+
+  @override
+  AbstractBool containsAll(covariant WrappedAbstractValue a) =>
+      _abstractValueDomain.containsAll(a._abstractValue);
+
+  @override
+  AbstractBool areDisjoint(
+          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
+      _abstractValueDomain.areDisjoint(a._abstractValue, b._abstractValue);
+
+  @override
+  AbstractValue intersection(
+          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
+      WrappedAbstractValue(_abstractValueDomain.intersection(
+          a._abstractValue, b._abstractValue));
+
+  @override
+  AbstractValue unionOfMany(covariant Iterable<AbstractValue> values) {
+    List<AbstractValue> unwrapped_Values = values
+        .map((element) => (element as WrappedAbstractValue)._abstractValue)
+        .toList();
+    return WrappedAbstractValue(
+        _abstractValueDomain.unionOfMany(unwrapped_Values));
+  }
+
+  @override
+  AbstractValue union(
+          covariant WrappedAbstractValue a, covariant WrappedAbstractValue b) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.union(a._abstractValue, b._abstractValue));
+
+  @override
+  AbstractBool isPrimitiveOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isStringOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isStringOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isString(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isString(value._abstractValue);
+
+  @override
+  AbstractBool isBooleanOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isBooleanOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isBoolean(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isBoolean(value._abstractValue);
+
+  @override
+  AbstractBool isDoubleOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isDoubleOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isDouble(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isDouble(value._abstractValue);
+
+  @override
+  AbstractBool isNumberOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isNumberOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isNumber(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isNumber(value._abstractValue);
+
+  @override
+  AbstractBool isIntegerOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isIntegerOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isPositiveIntegerOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPositiveIntegerOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isPositiveInteger(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPositiveInteger(value._abstractValue);
+
+  @override
+  AbstractBool isUInt31(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isUInt31(value._abstractValue);
+
+  @override
+  AbstractBool isUInt32(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isUInt32(value._abstractValue);
+
+  @override
+  AbstractBool isInteger(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isInteger(value._abstractValue);
+
+  @override
+  AbstractBool isInterceptor(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isInterceptor(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveString(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveString(value._abstractValue);
+
+  @override
+  AbstractBool isArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isArray(value._abstractValue);
+
+  @override
+  AbstractBool isMutableIndexable(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isMutableIndexable(value._abstractValue);
+
+  @override
+  AbstractBool isMutableArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isMutableArray(value._abstractValue);
+
+  @override
+  AbstractBool isExtendableArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isExtendableArray(value._abstractValue);
+
+  @override
+  AbstractBool isFixedArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isFixedArray(value._abstractValue);
+
+  @override
+  AbstractBool isIndexablePrimitive(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isIndexablePrimitive(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveArray(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveBoolean(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveBoolean(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitiveNumber(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitiveNumber(value._abstractValue);
+
+  @override
+  AbstractBool isPrimitive(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isPrimitive(value._abstractValue);
+
+  @override
+  AbstractBool isNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isNull(value._abstractValue);
+
+  @override
+  ClassEntity getExactClass(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.getExactClass(value._abstractValue);
+
+  @override
+  AbstractBool isExactOrNull(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isExactOrNull(value._abstractValue);
+
+  @override
+  AbstractBool isExact(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isExact(value._abstractValue);
+
+  @override
+  AbstractBool isEmpty(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isEmpty(value._abstractValue);
+
+  @override
+  AbstractBool isInstanceOf(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.isInstanceOf(value._abstractValue, cls);
+
+  @override
+  AbstractBool isInstanceOfOrNull(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.isInstanceOfOrNull(value._abstractValue, cls);
+
+  @override
+  AbstractBool containsOnlyType(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.containsOnlyType(value._abstractValue, cls);
+
+  @override
+  AbstractBool containsType(
+          covariant WrappedAbstractValue value, ClassEntity cls) =>
+      _abstractValueDomain.containsType(value._abstractValue, cls);
+
+  @override
+  AbstractValue includeNull(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.includeNull(value._abstractValue));
+
+  @override
+  AbstractValue excludeNull(covariant WrappedAbstractValue value) =>
+      WrappedAbstractValue(
+          _abstractValueDomain.excludeNull(value._abstractValue));
+
+  @override
+  AbstractBool couldBeTypedArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.couldBeTypedArray(value._abstractValue);
+
+  @override
+  AbstractBool isTypedArray(covariant WrappedAbstractValue value) =>
+      _abstractValueDomain.isTypedArray(value._abstractValue);
+
+  @override
+  AbstractValue createNullableSubtype(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNullableSubtype(cls));
+
+  @override
+  AbstractValue createNonNullSubtype(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNonNullSubtype(cls));
+
+  @override
+  AbstractValue createNonNullSubclass(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNonNullSubclass(cls));
+
+  @override
+  AbstractValue createNullableExact(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNullableExact(cls));
+
+  @override
+  AbstractValue createNonNullExact(ClassEntity cls) =>
+      WrappedAbstractValue(_abstractValueDomain.createNonNullExact(cls));
+
+  @override
+  AbstractValueWithPrecision createFromStaticType(DartType type,
+      {ClassRelation classRelation = ClassRelation.subtype, bool nullable}) {
+    var unwrapped = _abstractValueDomain.createFromStaticType(type,
+        classRelation: classRelation, nullable: nullable);
+    return AbstractValueWithPrecision(
+        WrappedAbstractValue(unwrapped.abstractValue), unwrapped.isPrecise);
+  }
+
+  @override
+  AbstractValue get asyncStarStreamType =>
+      WrappedAbstractValue(_abstractValueDomain.asyncStarStreamType);
+
+  @override
+  AbstractValue get asyncFutureType =>
+      WrappedAbstractValue(_abstractValueDomain.asyncFutureType);
+
+  @override
+  AbstractValue get syncStarIterableType =>
+      WrappedAbstractValue(_abstractValueDomain.syncStarIterableType);
+
+  @override
+  AbstractValue get emptyType =>
+      WrappedAbstractValue(_abstractValueDomain.emptyType);
+
+  @override
+  AbstractValue get constMapType =>
+      WrappedAbstractValue(_abstractValueDomain.constMapType);
+
+  @override
+  AbstractValue get constSetType =>
+      WrappedAbstractValue(_abstractValueDomain.constSetType);
+
+  @override
+  AbstractValue get constListType =>
+      WrappedAbstractValue(_abstractValueDomain.constListType);
+
+  @override
+  AbstractValue get positiveIntType =>
+      WrappedAbstractValue(_abstractValueDomain.positiveIntType);
+
+  @override
+  AbstractValue get uint32Type =>
+      WrappedAbstractValue(_abstractValueDomain.uint32Type);
+
+  @override
+  AbstractValue get uint31Type =>
+      WrappedAbstractValue(_abstractValueDomain.uint31Type);
+
+  @override
+  AbstractValue get fixedListType =>
+      WrappedAbstractValue(_abstractValueDomain.fixedListType);
+
+  @override
+  AbstractValue get growableListType =>
+      WrappedAbstractValue(_abstractValueDomain.growableListType);
+
+  @override
+  AbstractValue get nullType =>
+      WrappedAbstractValue(_abstractValueDomain.nullType);
+
+  @override
+  AbstractValue get nonNullType =>
+      WrappedAbstractValue(_abstractValueDomain.nonNullType);
+
+  @override
+  AbstractValue get mapType =>
+      WrappedAbstractValue(_abstractValueDomain.mapType);
+
+  @override
+  AbstractValue get setType =>
+      WrappedAbstractValue(_abstractValueDomain.setType);
+
+  @override
+  AbstractValue get listType =>
+      WrappedAbstractValue(_abstractValueDomain.listType);
+
+  @override
+  AbstractValue get stringType =>
+      WrappedAbstractValue(_abstractValueDomain.stringType);
+
+  @override
+  AbstractValue get numType =>
+      WrappedAbstractValue(_abstractValueDomain.numType);
+
+  @override
+  AbstractValue get doubleType =>
+      WrappedAbstractValue(_abstractValueDomain.doubleType);
+
+  @override
+  AbstractValue get intType =>
+      WrappedAbstractValue(_abstractValueDomain.intType);
+
+  @override
+  AbstractValue get boolType =>
+      WrappedAbstractValue(_abstractValueDomain.boolType);
+
+  @override
+  AbstractValue get functionType =>
+      WrappedAbstractValue(_abstractValueDomain.functionType);
+
+  @override
+  AbstractValue get typeType =>
+      WrappedAbstractValue(_abstractValueDomain.typeType);
+}
+
+class WrappedAbstractValueStrategy implements AbstractValueStrategy {
+  final AbstractValueStrategy _abstractValueStrategy;
+  const WrappedAbstractValueStrategy(this._abstractValueStrategy);
+
+  @override
+  AbstractValueDomain createDomain(JClosedWorld closedWorld) {
+    return WrappedAbstractValueDomain(
+        _abstractValueStrategy.createDomain(closedWorld));
+  }
+
+  @override
+  SelectorConstraintsStrategy createSelectorStrategy() {
+    return WrappedSelectorStrategy(
+        _abstractValueStrategy.createSelectorStrategy());
+  }
+}
+
+class WrappedSelectorStrategy implements SelectorConstraintsStrategy {
+  final SelectorConstraintsStrategy _selectorConstraintsStrategy;
+  const WrappedSelectorStrategy(this._selectorConstraintsStrategy);
+
+  @override
+  UniverseSelectorConstraints createSelectorConstraints(
+      Selector selector, Object initialConstraint) {
+    return WrappedUniverseSelectorConstraints(
+        _selectorConstraintsStrategy.createSelectorConstraints(
+            selector,
+            initialConstraint == null
+                ? null
+                : (initialConstraint as WrappedAbstractValue)._abstractValue));
+  }
+
+  @override
+  bool appliedUnnamed(DynamicUse dynamicUse, MemberEntity member,
+      covariant JClosedWorld world) {
+    return _selectorConstraintsStrategy.appliedUnnamed(
+        dynamicUse.withReceiverConstraint(
+            unwrapOrNull(dynamicUse.receiverConstraint)),
+        member,
+        world);
+  }
+}
+
+class WrappedUniverseSelectorConstraints
+    implements UniverseSelectorConstraints {
+  final UniverseSelectorConstraints _universeSelectorConstraints;
+  const WrappedUniverseSelectorConstraints(this._universeSelectorConstraints);
+
+  @override
+  bool addReceiverConstraint(Object constraint) =>
+      _universeSelectorConstraints.addReceiverConstraint(constraint == null
+          ? null
+          : (constraint as WrappedAbstractValue)._abstractValue);
+
+  @override
+  bool needsNoSuchMethodHandling(Selector selector, World world) =>
+      _universeSelectorConstraints.needsNoSuchMethodHandling(selector, world);
+
+  @override
+  bool canHit(MemberEntity element, Name name, World world) =>
+      _universeSelectorConstraints.canHit(element, name, world);
+
+  @override
+  String toString() => 'WrappedUniverseSelectorConstraints:$hashCode';
+}
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/constants.dart b/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
index 24626cd..935095e 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
@@ -52,7 +52,7 @@
   @override
   TypeMask visitDummyInterceptor(
       DummyInterceptorConstantValue constant, JClosedWorld closedWorld) {
-    return constant.abstractValue;
+    return _abstractValueDomain.dynamicType;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart
index 5c6b9ef..188a951 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/container_type_mask.dart
@@ -32,12 +32,12 @@
 
   /// Deserializes a [ContainerTypeMask] object from [source].
   factory ContainerTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask forwardTo = new TypeMask.readFromDataSource(source, domain);
     ir.TreeNode allocationNode = source.readTreeNodeOrNull();
     MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask elementType = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask elementType = new TypeMask.readFromDataSource(source, domain);
     int length = source.readIntOrNull();
     source.end(tag);
     return new ContainerTypeMask(
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart
index 2431ba8..cc54437 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/dictionary_type_mask.dart
@@ -29,15 +29,15 @@
 
   /// Deserializes a [DictionaryTypeMask] object from [source].
   factory DictionaryTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask forwardTo = new TypeMask.readFromDataSource(source, domain);
     ir.TreeNode allocationNode = source.readTreeNodeOrNull();
     MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask keyType = new TypeMask.readFromDataSource(source, closedWorld);
-    TypeMask valueType = new TypeMask.readFromDataSource(source, closedWorld);
-    Map<String, AbstractValue> typeMap = source.readStringMap(
-        () => new TypeMask.readFromDataSource(source, closedWorld));
+    TypeMask keyType = new TypeMask.readFromDataSource(source, domain);
+    TypeMask valueType = new TypeMask.readFromDataSource(source, domain);
+    Map<String, AbstractValue> typeMap = source
+        .readStringMap(() => new TypeMask.readFromDataSource(source, domain));
     source.end(tag);
     return new DictionaryTypeMask(forwardTo, allocationNode, allocationElement,
         keyType, valueType, typeMap);
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart
index 482bdc4..deb7d88 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/flat_type_mask.dart
@@ -76,13 +76,12 @@
 
   /// Deserializes a [FlatTypeMask] object from [source].
   factory FlatTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
     ClassEntity base = source.readClassOrNull();
     int flags = source.readInt();
     source.end(tag);
-    CommonMasks commonMasks = closedWorld.abstractValueDomain;
-    return commonMasks.getCachedMask(
+    return domain.getCachedMask(
         base, flags, () => new FlatTypeMask._(base, flags));
   }
 
@@ -593,10 +592,13 @@
   }
 
   @override
-  MemberEntity locateSingleMember(Selector selector, JClosedWorld closedWorld) {
+  MemberEntity locateSingleMember(Selector selector, CommonMasks domain) {
     if (isEmptyOrNull) return null;
-    if (closedWorld.includesClosureCall(selector, this)) return null;
-    Iterable<MemberEntity> targets = closedWorld.locateMembers(selector, this);
+    JClosedWorld closedWorld = domain._closedWorld;
+    if (closedWorld.includesClosureCallInDomain(selector, this, domain))
+      return null;
+    Iterable<MemberEntity> targets =
+        closedWorld.locateMembersInDomain(selector, this, domain);
     if (targets.length != 1) return null;
     MemberEntity result = targets.first;
     ClassEntity enclosing = result.enclosingClass;
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart
index ee4de92..ca3910d 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/forwarding_type_mask.dart
@@ -131,8 +131,8 @@
   }
 
   @override
-  MemberEntity locateSingleMember(Selector selector, JClosedWorld closedWorld) {
-    return forwardTo.locateSingleMember(selector, closedWorld);
+  MemberEntity locateSingleMember(Selector selector, CommonMasks domain) {
+    return forwardTo.locateSingleMember(selector, domain);
   }
 
   bool equalsDisregardNull(other) {
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart
index f6e6dc8..556be49 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/map_type_mask.dart
@@ -32,13 +32,13 @@
 
   /// Deserializes a [MapTypeMask] object from [source].
   factory MapTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask forwardTo = new TypeMask.readFromDataSource(source, domain);
     ir.TreeNode allocationNode = source.readTreeNodeOrNull();
     MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask keyType = new TypeMask.readFromDataSource(source, closedWorld);
-    TypeMask valueType = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask keyType = new TypeMask.readFromDataSource(source, domain);
+    TypeMask valueType = new TypeMask.readFromDataSource(source, domain);
     source.end(tag);
     return new MapTypeMask(
         forwardTo, allocationNode, allocationElement, keyType, valueType);
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index 0d0bada..a657685 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -785,7 +785,7 @@
   @override
   MemberEntity locateSingleMember(
       covariant TypeMask receiver, Selector selector) {
-    return receiver.locateSingleMember(selector, _closedWorld);
+    return receiver.locateSingleMember(selector, this);
   }
 
   @override
@@ -815,7 +815,7 @@
         mask.containsOnly(
             _closedWorld.commonElements.jsUnmodifiableArrayClass) ||
         mask.containsOnlyString(_closedWorld) ||
-        _closedWorld.abstractValueDomain.isTypedArray(mask).isDefinitelyTrue) {
+        isTypedArray(mask).isDefinitelyTrue) {
       return AbstractBool.True;
     }
     return AbstractBool.Maybe;
@@ -963,7 +963,7 @@
   @override
   TypeMask readAbstractValueFromDataSource(DataSource source) {
     return source.readCached<TypeMask>(
-        () => new TypeMask.readFromDataSource(source, _closedWorld));
+        () => new TypeMask.readFromDataSource(source, this));
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart
index c62db3e..cfe96da 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/set_type_mask.dart
@@ -29,12 +29,12 @@
 
   /// Deserializes a [SetTypeMask] object from [source].
   factory SetTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask forwardTo = new TypeMask.readFromDataSource(source, domain);
     ir.TreeNode allocationNode = source.readTreeNodeOrNull();
     MemberEntity allocationElement = source.readMemberOrNull();
-    TypeMask elementType = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask elementType = new TypeMask.readFromDataSource(source, domain);
     source.end(tag);
     return new SetTypeMask(
         forwardTo, allocationNode, allocationElement, elementType);
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart
index 19d3e76..f98ad55 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/type_mask.dart
@@ -222,24 +222,23 @@
   }
 
   /// Deserializes a [TypeMask] object from [source].
-  factory TypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+  factory TypeMask.readFromDataSource(DataSource source, CommonMasks domain) {
     TypeMaskKind kind = source.readEnum(TypeMaskKind.values);
     switch (kind) {
       case TypeMaskKind.flat:
-        return new FlatTypeMask.readFromDataSource(source, closedWorld);
+        return new FlatTypeMask.readFromDataSource(source, domain);
       case TypeMaskKind.union:
-        return new UnionTypeMask.readFromDataSource(source, closedWorld);
+        return new UnionTypeMask.readFromDataSource(source, domain);
       case TypeMaskKind.container:
-        return new ContainerTypeMask.readFromDataSource(source, closedWorld);
+        return new ContainerTypeMask.readFromDataSource(source, domain);
       case TypeMaskKind.set:
-        return new SetTypeMask.readFromDataSource(source, closedWorld);
+        return new SetTypeMask.readFromDataSource(source, domain);
       case TypeMaskKind.map:
-        return new MapTypeMask.readFromDataSource(source, closedWorld);
+        return new MapTypeMask.readFromDataSource(source, domain);
       case TypeMaskKind.dictionary:
-        return new DictionaryTypeMask.readFromDataSource(source, closedWorld);
+        return new DictionaryTypeMask.readFromDataSource(source, domain);
       case TypeMaskKind.value:
-        return new ValueTypeMask.readFromDataSource(source, closedWorld);
+        return new ValueTypeMask.readFromDataSource(source, domain);
     }
     throw new UnsupportedError("Unexpected TypeMaskKind $kind.");
   }
@@ -415,5 +414,5 @@
 
   /// Returns the [element] that is known to always be hit at runtime
   /// on this mask. Returns null if there is none.
-  MemberEntity locateSingleMember(Selector selector, JClosedWorld closedWorld);
+  MemberEntity locateSingleMember(Selector selector, CommonMasks domain);
 }
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart
index 762dfc4..a4ffd6d 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/union_type_mask.dart
@@ -30,10 +30,10 @@
 
   /// Deserializes a [UnionTypeMask] object from [source].
   factory UnionTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
-    List<FlatTypeMask> disjointMasks = source
-        .readList(() => new TypeMask.readFromDataSource(source, closedWorld));
+    List<FlatTypeMask> disjointMasks =
+        source.readList(() => new TypeMask.readFromDataSource(source, domain));
     bool isNullable = source.readBool();
     source.end(tag);
     return new UnionTypeMask._internal(disjointMasks, isNullable);
@@ -421,11 +421,11 @@
   }
 
   @override
-  MemberEntity locateSingleMember(Selector selector, JClosedWorld closedWorld) {
+  MemberEntity locateSingleMember(Selector selector, CommonMasks domain) {
     MemberEntity candidate;
     for (FlatTypeMask mask in disjointMasks) {
       if (isNullable) mask = mask.nullable();
-      MemberEntity current = mask.locateSingleMember(selector, closedWorld);
+      MemberEntity current = mask.locateSingleMember(selector, domain);
       if (current == null) {
         return null;
       } else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart b/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart
index 94e0284..38486ab 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/value_type_mask.dart
@@ -17,9 +17,9 @@
 
   /// Deserializes a [ValueTypeMask] object from [source].
   factory ValueTypeMask.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld) {
+      DataSource source, CommonMasks domain) {
     source.begin(tag);
-    TypeMask forwardTo = new TypeMask.readFromDataSource(source, closedWorld);
+    TypeMask forwardTo = new TypeMask.readFromDataSource(source, domain);
     ConstantValue constant = source.readConstant();
     source.end(tag);
     return new ValueTypeMask(forwardTo, constant);
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index 53f5989..51740c4 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -225,6 +225,9 @@
       case TypeUseKind.TYPE_ARGUMENT:
         _worldBuilder.registerTypeArgument(type);
         break;
+      case TypeUseKind.CONSTRUCTOR_REFERENCE:
+        _worldBuilder.registerConstructorReference(type);
+        break;
       case TypeUseKind.CONST_INSTANTIATION:
         failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
         break;
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index 842a94e..ed37f59 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -203,6 +203,7 @@
         case TypeUseKind.RTI_VALUE:
         case TypeUseKind.TYPE_ARGUMENT:
         case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
+        case TypeUseKind.CONSTRUCTOR_REFERENCE:
           failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
           break;
       }
diff --git a/pkg/compiler/lib/src/js_backend/specialized_checks.dart b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
index 25156d2..5802406 100644
--- a/pkg/compiler/lib/src/js_backend/specialized_checks.dart
+++ b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
@@ -97,6 +97,7 @@
       OutputUnitData outputUnitData = closedWorld.outputUnitData;
 
       if (classHierarchy.hasOnlySubclasses(element) &&
+          classHierarchy.isInstantiated(element) &&
           !interceptorData.isInterceptedClass(element) &&
           outputUnitData.hasOnlyNonDeferredImportPathsToClass(
               graph.element, element)) {
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 4e04562..7abd26f 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -265,6 +265,7 @@
   final List<Field> staticFieldsForReflection;
   final bool hasRtiField; // Per-instance runtime type information pseudo-field.
   final bool onlyForRti;
+  final bool onlyForConstructor;
   final bool isDirectlyInstantiated;
   final bool isNative;
   final bool isClosureBaseClass; // Common base class for closures.
@@ -307,12 +308,14 @@
       this.functionTypeIndex,
       {this.hasRtiField,
       this.onlyForRti,
+      this.onlyForConstructor,
       this.isDirectlyInstantiated,
       this.isNative,
       this.isClosureBaseClass,
       this.isSoftDeferred = false,
       this.isSuperMixinApplication}) {
     assert(onlyForRti != null);
+    assert(onlyForConstructor != null);
     assert(isDirectlyInstantiated != null);
     assert(isNative != null);
     assert(isClosureBaseClass != null);
@@ -359,6 +362,7 @@
       js.Expression functionTypeIndex,
       {bool hasRtiField,
       bool onlyForRti,
+      bool onlyForConstructor,
       bool isDirectlyInstantiated})
       : super(
             element,
@@ -375,6 +379,7 @@
             functionTypeIndex,
             hasRtiField: hasRtiField,
             onlyForRti: onlyForRti,
+            onlyForConstructor: onlyForConstructor,
             isDirectlyInstantiated: isDirectlyInstantiated,
             isNative: false,
             isClosureBaseClass: false,
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 9058ec1..49a1d63 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -22,27 +22,23 @@
   final Map<MemberEntity, js.Expression> _generatedCode;
   final Sorter _sorter;
 
-  final Set<ClassEntity> neededClasses = new Set<ClassEntity>();
+  final Set<ClassEntity> neededClasses = {};
+  final Set<ClassEntity> classesOnlyNeededForRti = {};
   // This field is set in [computeNeededDeclarations].
-  Set<ClassEntity> classesOnlyNeededForRti;
-  final Map<OutputUnit, List<ClassEntity>> outputClassLists =
-      new Map<OutputUnit, List<ClassEntity>>();
-  final Map<OutputUnit, List<ConstantValue>> outputConstantLists =
-      new Map<OutputUnit, List<ConstantValue>>();
-  final Map<OutputUnit, List<MemberEntity>> outputStaticLists =
-      new Map<OutputUnit, List<MemberEntity>>();
-  final Map<OutputUnit, List<FieldEntity>> outputStaticNonFinalFieldLists =
-      new Map<OutputUnit, List<FieldEntity>>();
+  Set<ClassEntity> classesOnlyNeededForConstructor;
+  final Map<OutputUnit, List<ClassEntity>> outputClassLists = {};
+  final Map<OutputUnit, List<ConstantValue>> outputConstantLists = {};
+  final Map<OutputUnit, List<MemberEntity>> outputStaticLists = {};
+  final Map<OutputUnit, List<FieldEntity>> outputStaticNonFinalFieldLists = {};
   final Map<OutputUnit, List<FieldEntity>> outputLazyStaticFieldLists = {};
-  final Map<OutputUnit, Set<LibraryEntity>> outputLibraryLists =
-      new Map<OutputUnit, Set<LibraryEntity>>();
+  final Map<OutputUnit, Set<LibraryEntity>> outputLibraryLists = {};
 
   /// True, if the output contains a constant list.
   ///
   /// This flag is updated in [computeNeededConstants].
   bool outputContainsConstantList = false;
 
-  final List<ClassEntity> nativeClassesAndSubclasses = <ClassEntity>[];
+  final List<ClassEntity> nativeClassesAndSubclasses = [];
 
   Collector(
       this._commonElements,
@@ -59,7 +55,7 @@
       this._sorter);
 
   Set<ClassEntity> computeInterceptorsReferencedFromConstants() {
-    Set<ClassEntity> classes = new Set<ClassEntity>();
+    Set<ClassEntity> classes = {};
     Iterable<ConstantValue> constants = _codegenWorld.getConstantsForEmission();
     for (ConstantValue constant in constants) {
       if (constant is InterceptorConstantValue) {
@@ -73,14 +69,14 @@
   /// Return a function that returns true if its argument is a class
   /// that needs to be emitted.
   Function computeClassFilter(Iterable<ClassEntity> backendTypeHelpers) {
-    Set<ClassEntity> unneededClasses = new Set<ClassEntity>();
+    Set<ClassEntity> unneededClasses = {};
     // The [Bool] class is not marked as abstract, but has a factory
     // constructor that always throws. We never need to emit it.
     unneededClasses.add(_commonElements.boolClass);
 
     // Go over specialized interceptors and then constants to know which
     // interceptors are needed.
-    Set<ClassEntity> needed = new Set<ClassEntity>();
+    Set<ClassEntity> needed = {};
     for (SpecializedGetInterceptor interceptor
         in _oneShotInterceptorData.specializedGetInterceptors) {
       needed.addAll(interceptor.classes);
@@ -134,9 +130,7 @@
         // TODO(sigurdm): We should track those constants.
         constantUnit = _outputUnitData.mainOutputUnit;
       }
-      outputConstantLists
-          .putIfAbsent(constantUnit, () => new List<ConstantValue>())
-          .add(constant);
+      outputConstantLists.putIfAbsent(constantUnit, () => []).add(constant);
     }
   }
 
@@ -178,14 +172,19 @@
         .toSet();
     neededClasses.addAll(mixinClasses);
 
-    // 3. Find all classes needed for rti.
+    // 3. Add classes only needed for their constructors.
+    classesOnlyNeededForConstructor = _codegenWorld.constructorReferences
+        .where((cls) => !neededClasses.contains(cls))
+        .toSet();
+    neededClasses.addAll(classesOnlyNeededForConstructor);
+
+    // 4. Find all classes needed for rti.
     // It is important that this is the penultimate step, at this point,
     // neededClasses must only contain classes that have been resolved and
     // codegen'd. The rtiNeededClasses may contain additional classes, but
     // these are thought to not have been instantiated, so we need to be able
     // to identify them later and make sure we only emit "empty shells" without
     // fields, etc.
-    classesOnlyNeededForRti = new Set<ClassEntity>();
     for (ClassEntity cls in _rtiNeededClasses) {
       if (backendTypeHelpers.contains(cls)) continue;
       while (cls != null && !neededClasses.contains(cls)) {
@@ -196,23 +195,22 @@
 
     neededClasses.addAll(classesOnlyNeededForRti);
 
-    // 4. Finally, sort the classes.
+    // 5. Finally, sort the classes.
     List<ClassEntity> sortedClasses = _sorter.sortClasses(neededClasses);
 
     for (ClassEntity cls in sortedClasses) {
       if (_nativeData.isNativeOrExtendsNative(cls) &&
-          !classesOnlyNeededForRti.contains(cls)) {
+          !classesOnlyNeededForRti.contains(cls) &&
+          !classesOnlyNeededForConstructor.contains(cls)) {
         // For now, native classes and related classes cannot be deferred.
         nativeClassesAndSubclasses.add(cls);
         assert(!_outputUnitData.isDeferredClass(cls), failedAt(cls));
         outputClassLists
-            .putIfAbsent(
-                _outputUnitData.mainOutputUnit, () => new List<ClassEntity>())
+            .putIfAbsent(_outputUnitData.mainOutputUnit, () => [])
             .add(cls);
       } else {
         outputClassLists
-            .putIfAbsent(_outputUnitData.outputUnitForClass(cls),
-                () => new List<ClassEntity>())
+            .putIfAbsent(_outputUnitData.outputUnitForClass(cls), () => [])
             .add(cls);
       }
     }
@@ -227,8 +225,7 @@
 
     for (MemberEntity member in _sorter.sortMembers(elements)) {
       List<MemberEntity> list = outputStaticLists.putIfAbsent(
-          _outputUnitData.outputUnitForMember(member),
-          () => new List<MemberEntity>());
+          _outputUnitData.outputUnitForMember(member), () => []);
       list.add(member);
     }
   }
@@ -236,8 +233,7 @@
   void computeNeededStaticNonFinalFields() {
     addToOutputUnit(FieldEntity element) {
       List<FieldEntity> list = outputStaticNonFinalFieldLists.putIfAbsent(
-          _outputUnitData.outputUnitForMember(element),
-          () => new List<FieldEntity>());
+          _outputUnitData.outputUnitForMember(element), () => []);
       list.add(element);
     }
 
@@ -286,16 +282,12 @@
     _generatedCode.keys.forEach((MemberEntity element) {
       OutputUnit unit = _outputUnitData.outputUnitForMember(element);
       LibraryEntity library = element.library;
-      outputLibraryLists
-          .putIfAbsent(unit, () => new Set<LibraryEntity>())
-          .add(library);
+      outputLibraryLists.putIfAbsent(unit, () => {}).add(library);
     });
     neededClasses.forEach((ClassEntity element) {
       OutputUnit unit = _outputUnitData.outputUnitForClass(element);
       LibraryEntity library = element.library;
-      outputLibraryLists
-          .putIfAbsent(unit, () => new Set<LibraryEntity>())
-          .add(library);
+      outputLibraryLists.putIfAbsent(unit, () => {}).add(library);
     });
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 04d085e..e2ad389 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -634,6 +634,8 @@
   }
 
   Class _buildClass(ClassEntity cls) {
+    bool onlyForConstructor =
+        collector.classesOnlyNeededForConstructor.contains(cls);
     bool onlyForRti = collector.classesOnlyNeededForRti.contains(cls);
     bool hasRtiField = _rtiNeed.classNeedsTypeArguments(cls);
     if (_nativeData.isJsInteropClass(cls)) {
@@ -641,6 +643,7 @@
       // if it does not we can suppress it completely.
       onlyForRti = true;
     }
+    bool onlyForConstructorOrRti = onlyForConstructor || onlyForRti;
     bool isClosureBaseClass = cls == _commonElements.closureClass;
 
     List<Method> methods = [];
@@ -700,14 +703,14 @@
       callStubs.add(_buildStubMethod(name, function));
     }
 
-    if (_commonElements.isInstantiationClass(cls) && !onlyForRti) {
+    if (_commonElements.isInstantiationClass(cls) && !onlyForConstructorOrRti) {
       callStubs.addAll(_generateInstantiationStubs(cls));
     }
 
     // MixinApplications run through the members of their mixin. Here, we are
     // only interested in direct members.
     bool isSuperMixinApplication = false;
-    if (!onlyForRti) {
+    if (!onlyForConstructorOrRti) {
       if (_elementEnvironment.isSuperMixinApplication(cls)) {
         List<MemberEntity> members = <MemberEntity>[];
         void add(MemberEntity member) {
@@ -732,14 +735,14 @@
       }
     }
     bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
-    List<Field> instanceFields = onlyForRti
-        ? const <Field>[]
+    List<Field> instanceFields = onlyForConstructorOrRti
+        ? const []
         : _buildFields(
             cls: cls,
             visitStatics: false,
             isHolderInterceptedClass: isInterceptedClass);
-    List<Field> staticFieldsForReflection = onlyForRti
-        ? const <Field>[]
+    List<Field> staticFieldsForReflection = onlyForConstructorOrRti
+        ? const []
         : _buildFields(
             cls: cls,
             visitStatics: true,
@@ -792,7 +795,7 @@
 
     Class result;
     if (_elementEnvironment.isMixinApplication(cls) &&
-        !onlyForRti &&
+        !onlyForConstructorOrRti &&
         !isSuperMixinApplication) {
       assert(!_nativeData.isNativeClass(cls));
       assert(methods.isEmpty);
@@ -811,7 +814,8 @@
           typeTests.functionTypeIndex,
           isDirectlyInstantiated: isInstantiated,
           hasRtiField: hasRtiField,
-          onlyForRti: onlyForRti);
+          onlyForRti: onlyForRti,
+          onlyForConstructor: onlyForConstructor);
     } else {
       result = new Class(
           cls,
@@ -829,6 +833,7 @@
           isDirectlyInstantiated: isInstantiated,
           hasRtiField: hasRtiField,
           onlyForRti: onlyForRti,
+          onlyForConstructor: onlyForConstructor,
           isNative: _nativeData.isNativeClass(cls),
           isClosureBaseClass: isClosureBaseClass,
           isSoftDeferred: _isSoftDeferred(cls),
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 2db2f31..20f91bd 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -2003,15 +2003,15 @@
           fieldNumber++;
         }
       } else if (variable is TypeVariableTypeWithContext) {
-        _constructClosureField(
-            localsMap.getLocalTypeVariable(variable.type, this),
-            closureClassInfo,
-            memberThisType,
-            memberMap,
-            variable.type.parameter,
-            true,
-            false,
-            fieldNumber);
+        Local capturedLocal =
+            localsMap.getLocalTypeVariable(variable.type, this);
+        // We can have distinct TypeVariableTypeWithContexts that have the same
+        // local variable but with different nullabilities. We only want to
+        // construct a closure field once for each local variable.
+        if (closureClassInfo.localToFieldMap.containsKey(capturedLocal))
+          continue;
+        _constructClosureField(capturedLocal, closureClassInfo, memberThisType,
+            memberMap, variable.type.parameter, true, false, fieldNumber);
         fieldNumber++;
       } else {
         throw new UnsupportedError("Unexpected field node type: $variable");
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index e510eff..2b5263a 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -457,7 +457,8 @@
       getLubOfInstantiatedSubtypes(commonElements.functionClass);
 
   @override
-  bool includesClosureCall(Selector selector, AbstractValue receiver) {
+  bool includesClosureCallInDomain(Selector selector, AbstractValue receiver,
+      AbstractValueDomain abstractValueDomain) {
     return selector.name == Identifiers.call &&
         (receiver == null ||
             // This is logically equivalent to the former implementation using
@@ -480,6 +481,11 @@
   }
 
   @override
+  bool includesClosureCall(Selector selector, AbstractValue receiver) {
+    return includesClosureCallInDomain(selector, receiver, abstractValueDomain);
+  }
+
+  @override
   AbstractValue computeReceiverType(Selector selector, AbstractValue receiver) {
     _ensureFunctionSet();
     if (includesClosureCall(selector, receiver)) {
@@ -489,12 +495,18 @@
   }
 
   @override
-  Iterable<MemberEntity> locateMembers(
-      Selector selector, AbstractValue receiver) {
+  Iterable<MemberEntity> locateMembersInDomain(Selector selector,
+      AbstractValue receiver, AbstractValueDomain abstractValueDomain) {
     _ensureFunctionSet();
     return _allFunctions.filter(selector, receiver, abstractValueDomain);
   }
 
+  @override
+  Iterable<MemberEntity> locateMembers(
+      Selector selector, AbstractValue receiver) {
+    return locateMembersInDomain(selector, receiver, abstractValueDomain);
+  }
+
   bool hasAnyUserDefinedGetter(Selector selector, AbstractValue receiver) {
     _ensureFunctionSet();
     return _allFunctions
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index f7a7e97..3d43255 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -151,16 +151,6 @@
             _nativeBasicDataBuilder.markAsJsInteropMember(
                 constructor, memberName);
           }
-
-          if (constructor.isFactoryConstructor && isAnonymous) {
-            if (constructor.parameterStructure.positionalParameters > 0) {
-              reporter.reportErrorMessage(
-                  constructor,
-                  MessageKind
-                      .JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
-                  {'cls': cls.name});
-            }
-          }
         });
       } else {
         elementEnvironment.forEachLocalClassMember(cls, (MemberEntity member) {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index a1b0a83..a2f9c2c 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -235,6 +235,13 @@
   /// Whether to generate code containing user's `assert` statements.
   bool enableUserAssertions = false;
 
+  /// Whether to generate code asserting that non-nullable parameters in opt-in
+  /// code are not null. In mixed mode code (some opting into non-nullable, some
+  /// not), null-safety is unsound, allowing `null` values to be assigned to
+  /// variables with non-nullable types. This assertion lets the opt-in code
+  /// operate with a stronger guarantee.
+  bool enableNullAssertions = false;
+
   /// Whether to generate a source-map file together with the output program.
   bool generateSourceMap = true;
 
@@ -445,6 +452,8 @@
           !_hasOption(options, Flags.disableNativeLiveTypeAnalysis)
       ..enableUserAssertions = _hasOption(options, Flags.enableCheckedMode) ||
           _hasOption(options, Flags.enableAsserts)
+      ..enableNullAssertions = _hasOption(options, Flags.enableCheckedMode) ||
+          _hasOption(options, Flags.enableNullAssertions)
       ..experimentalTrackAllocations =
           _hasOption(options, Flags.experimentalTrackAllocations)
       ..experimentalAllocationsPath = _extractStringOption(
diff --git a/pkg/compiler/lib/src/serialization/abstract_sink.dart b/pkg/compiler/lib/src/serialization/abstract_sink.dart
index 19b110a..c127c695b 100644
--- a/pkg/compiler/lib/src/serialization/abstract_sink.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_sink.dart
@@ -537,8 +537,6 @@
         writeOutputUnitReference(constant.unit);
         break;
       case ConstantValueKind.DUMMY_INTERCEPTOR:
-        DummyInterceptorConstantValue constant = value;
-        writeAbstractValue(constant.abstractValue);
         break;
       case ConstantValueKind.UNREACHABLE:
         break;
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index 6a2fc22..26f9bc1 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -543,8 +543,7 @@
         OutputUnit unit = readOutputUnitReference();
         return new DeferredGlobalConstantValue(constant, unit);
       case ConstantValueKind.DUMMY_INTERCEPTOR:
-        AbstractValue abstractValue = readAbstractValue();
-        return new DummyInterceptorConstantValue(abstractValue);
+        return DummyInterceptorConstantValue();
       case ConstantValueKind.UNREACHABLE:
         return UnreachableConstantValue();
       case ConstantValueKind.JS_NAME:
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 703c2d0..24104e5 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -588,13 +588,15 @@
       // If the method is intercepted, we want the actual receiver
       // to be the first parameter.
       graph.entry.addBefore(graph.entry.last, parameter);
+      DartType type = _getDartTypeIfValid(node.type);
       HInstruction value = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
-          field, parameter, _getDartTypeIfValid(node.type));
+          field, parameter, type);
       // TODO(sra): Pass source information to
       // [potentiallyCheckOrTrustTypeOfParameter].
       // TODO(sra): The source information should indiciate the field and
       // possibly its type but not the initializer.
       value.sourceInformation ??= _sourceInformationBuilder.buildSet(node);
+      value = _potentiallyAssertNotNull(node, value, type);
       if (!_fieldAnalysis.getFieldData(field).isElided) {
         add(HFieldSet(_abstractValueDomain, field, thisInstruction, value));
       }
@@ -1237,27 +1239,6 @@
         parameterStructure: function.parameterStructure,
         checks: _checksForFunction(function));
 
-    // If [functionNode] is `operator==` we explicitly add a null check at the
-    // beginning of the method. This is to avoid having call sites do the null
-    // check.
-    if (function.name == '==') {
-      if (!_commonElements.operatorEqHandlesNullArgument(function)) {
-        _handleIf(
-            visitCondition: () {
-              HParameterValue parameter = parameters.values.first;
-              push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
-                  _abstractValueDomain.boolType));
-            },
-            visitThen: () {
-              _closeAndGotoExit(HReturn(
-                  _abstractValueDomain,
-                  graph.addConstantBool(false, closedWorld),
-                  _sourceInformationBuilder.buildReturn(functionNode)));
-            },
-            visitElse: null,
-            sourceInformation: _sourceInformationBuilder.buildIf(functionNode));
-      }
-    }
     if (const bool.fromEnvironment('unreachable-throw')) {
       var emptyParameters = parameters.values.where((p) =>
           _abstractValueDomain.isEmpty(p.instructionType).isDefinitelyTrue);
@@ -1432,7 +1413,8 @@
         newParameter = _typeBuilder.trustTypeOfParameter(
             targetElement, newParameter, type);
       }
-
+      // TODO(sra): Hoist out of loop.
+      newParameter = _potentiallyAssertNotNull(variable, newParameter, type);
       localsHandler.updateLocal(local, newParameter);
     }
 
@@ -1459,6 +1441,41 @@
     }
   }
 
+  /// In mixed mode, inserts an assertion of the form `assert(x != null)` for
+  /// parameters in opt-in libraries that have a static type that cannot be
+  /// nullable under a strong interpretation.
+  HInstruction _potentiallyAssertNotNull(
+      ir.TreeNode context, HInstruction value, DartType type) {
+    if (!options.enableNullAssertions) return value;
+    if (!_isNonNullableByDefault(context)) return value;
+    if (!dartTypes.isNonNullableIfSound(type)) return value;
+
+    if (options.enableUserAssertions) {
+      pushCheckNull(value);
+      push(HNot(pop(), _abstractValueDomain.boolType));
+      var sourceInformation = _sourceInformationBuilder.buildAssert(context);
+      _pushStaticInvocation(
+          _commonElements.assertHelper,
+          <HInstruction>[pop()],
+          _typeInferenceMap.getReturnTypeOf(_commonElements.assertHelper),
+          const <DartType>[],
+          sourceInformation: sourceInformation);
+      pop();
+      return value;
+    } else {
+      HInstruction nullCheck = HNullCheck(
+          value, _abstractValueDomain.excludeNull(value.instructionType))
+        ..sourceInformation = value.sourceInformation;
+      add(nullCheck);
+      return nullCheck;
+    }
+  }
+
+  bool _isNonNullableByDefault(ir.TreeNode node) {
+    if (node is ir.Library) return node.isNonNullableByDefault;
+    return _isNonNullableByDefault(node.parent);
+  }
+
   /// Builds a SSA graph for FunctionNodes of external methods. This produces a
   /// graph for a method with Dart calling conventions that forwards to the
   /// actual external method.
@@ -1617,6 +1634,29 @@
     _addClassTypeVariablesIfNeeded(member);
     _addFunctionTypeVariablesIfNeeded(member);
 
+    // If [member] is `operator==` we explicitly add a null check at the
+    // beginning of the method. This is to avoid having call sites do the null
+    // check. The null check is added before the argument type checks since in
+    // strong mode, the parameter type might be non-nullable.
+    if (member.name == '==') {
+      if (!_commonElements.operatorEqHandlesNullArgument(member)) {
+        _handleIf(
+            visitCondition: () {
+              HParameterValue parameter = parameters.values.first;
+              push(new HIdentity(parameter, graph.addConstantNull(closedWorld),
+                  _abstractValueDomain.boolType));
+            },
+            visitThen: () {
+              _closeAndGotoExit(HReturn(
+                  _abstractValueDomain,
+                  graph.addConstantBool(false, closedWorld),
+                  _sourceInformationBuilder.buildReturn(functionNode)));
+            },
+            visitElse: null,
+            sourceInformation: _sourceInformationBuilder.buildIf(functionNode));
+      }
+    }
+
     if (functionNode != null) {
       _potentiallyAddFunctionParameterTypeChecks(functionNode, checks);
     }
@@ -5493,10 +5533,9 @@
 
       // Don't inline operator== methods if the parameter can be null.
       if (function.name == '==') {
-        if (function.enclosingClass != _commonElements.objectClass &&
-            providedArguments[1]
-                .isNull(_abstractValueDomain)
-                .isPotentiallyTrue) {
+        if (providedArguments[1]
+            .isNull(_abstractValueDomain)
+            .isPotentiallyTrue) {
           return false;
         }
       }
@@ -6046,6 +6085,8 @@
         checkedOrTrusted = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
             function, argument, type);
       }
+      checkedOrTrusted =
+          _potentiallyAssertNotNull(variable, checkedOrTrusted, type);
       localsHandler.updateLocal(parameter, checkedOrTrusted);
     });
   }
@@ -6267,7 +6308,7 @@
 
     AbstractValue unwrappedType = kernelBuilder._typeInferenceMap
         .getReturnTypeOf(kernelBuilder._commonElements.exceptionUnwrapper);
-    if (!kernelBuilder.options.useLegacySubtyping) {
+    if (kernelBuilder.options.useNullSafety) {
       // Global type analysis does not currently understand that strong mode
       // `Object` is not nullable, so is imprecise in the return type of the
       // unwrapper, which leads to unnecessary checks for 'on Object'.
@@ -6285,7 +6326,6 @@
     int catchesIndex = 0;
 
     void pushCondition(ir.Catch catchBlock) {
-      // `guard` is often `dynamic`, which generates `true`.
       kernelBuilder._pushIsTest(catchBlock.guard, unwrappedException,
           kernelBuilder._sourceInformationBuilder.buildCatch(catchBlock));
     }
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 85de782..661962a 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -3032,7 +3032,7 @@
                 !dartType.baseType.isObject &&
                 dartType.baseType is! NeverType));
         InterfaceType type = dartType.withoutNullability;
-        _registry.registerTypeUse(TypeUse.instanceConstructor(type));
+        _registry.registerTypeUse(TypeUse.constructorReference(type));
         test = handleNegative(js.js('# instanceof #',
             [value, _emitter.constructorAccess(type.element)]));
     }
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index be25134..6aa5a3c 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -290,8 +290,7 @@
       return;
     }
 
-    ConstantValue constant =
-        DummyInterceptorConstantValue(receiverArgument.instructionType);
+    ConstantValue constant = DummyInterceptorConstantValue();
     HConstant dummy = graph.addConstant(constant, _closedWorld);
     receiverArgument.usedBy.remove(node);
     node.inputs[1] = dummy;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 86310fe..cc52e28 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -4130,26 +4130,30 @@
   AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
   AbstractValue subsetType = expression.instructionType;
   AbstractValue supersetType = checkedAbstractValue.abstractValue;
+  AbstractBool expressionIsNull = expression.isNull(abstractValueDomain);
 
-  if (useNullSafety &&
-      expression.isNull(abstractValueDomain).isDefinitelyTrue) {
-    if (dartType.isObject) return AbstractBool.False;
-    if (closedWorld.dartTypes.isTopType(dartType) ||
-        dartType is NullableType ||
-        dartType.isNull) {
-      return AbstractBool.True;
-    }
-    if (dartType is TypeVariableType || dartType is FunctionTypeVariable) {
-      return AbstractBool.Maybe;
-    }
-    if (dartType is LegacyType) {
-      DartType baseType = dartType.baseType;
-      if (baseType is NeverType) return AbstractBool.True;
-      if (baseType is TypeVariableType || baseType is FunctionTypeVariable) {
+  if (useNullSafety) {
+    if (expressionIsNull.isDefinitelyTrue) {
+      if (dartType.isObject) return AbstractBool.False;
+      if (closedWorld.dartTypes.isTopType(dartType) ||
+          dartType is NullableType ||
+          dartType.isNull) {
+        return AbstractBool.True;
+      }
+      if (dartType is TypeVariableType || dartType is FunctionTypeVariable) {
         return AbstractBool.Maybe;
       }
+      if (dartType is LegacyType) {
+        DartType baseType = dartType.baseType;
+        if (baseType is NeverType) return AbstractBool.True;
+        if (baseType is TypeVariableType || baseType is FunctionTypeVariable) {
+          return AbstractBool.Maybe;
+        }
+      }
+      return AbstractBool.False;
+    } else if (expressionIsNull.isPotentiallyTrue) {
+      if (dartType.isObject) return AbstractBool.Maybe;
     }
-    return AbstractBool.False;
   }
 
   if (checkedAbstractValue.isPrecise &&
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index e21dd7d..a410a55 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -1887,10 +1887,6 @@
     if (typeInput is HLoadType) {
       TypeExpressionRecipe recipe = typeInput.typeExpression;
       DartType dartType = recipe.type;
-      if (_closedWorld.dartTypes.isTopType(dartType)) {
-        return _graph.addConstantBool(true, _closedWorld);
-      }
-
       IsTestSpecialization specialization =
           SpecializedChecks.findIsTestSpecialization(
               dartType, _graph, _closedWorld);
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 5e5d2b9..7a176fa 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -129,12 +129,20 @@
     CheckPolicy parameterCheckPolicy = builder.closedWorld.annotationsData
         .getParameterCheckPolicy(memberContext);
 
-    /// Dart semantics check against null outside the method definition,
-    /// however dart2js moves the null check to the callee for performance
-    /// reasons. As a result the body cannot trust or check that the type is not
-    /// nullable.
-    if (builder.options.useNullSafety && memberContext.name == '==') {
-      type = _closedWorld.dartTypes.nullableType(type);
+    if (memberContext.name == '==') {
+      // Dart semantics for `a == b` check `a` and `b` against `null` outside
+      // the method invocation. For code size reasons, dart2js implements the
+      // null check on `a` by implementing `JSNull.==`, and the null check on
+      // `b` by injecting the check into `==` methods, before any type checks.
+      //
+      // There are a small number of runtime library methods that do not have
+      // the check injected. For these we need to widen the argument type to
+      // avoid generating code that rejects `null`. In practice these are always
+      // widened to TOP.
+      if (_closedWorld.commonElements
+          .operatorEqHandlesNullArgument(memberContext)) {
+        type = _closedWorld.dartTypes.nullableType(type);
+      }
     }
     if (parameterCheckPolicy.isTrusted) {
       checkedOrTrusted = _trustType(original, type);
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index d58a3b0..21cc9f2 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -67,6 +67,8 @@
   // TODO(johnniwinther): Improve semantic precision.
   Iterable<ClassEntity> get directlyInstantiatedClasses;
 
+  Iterable<ClassEntity> get constructorReferences;
+
   /// All directly or indirectly instantiated classes.
   Iterable<ClassEntity> get instantiatedClasses;
 
@@ -108,60 +110,53 @@
   /// Invariant: Elements are declaration elements.
   // TODO(johnniwinther): [_directlyInstantiatedClasses] and
   // [_instantiatedTypes] sets should be merged.
-  final Set<ClassEntity> _directlyInstantiatedClasses = new Set<ClassEntity>();
+  final Set<ClassEntity> _directlyInstantiatedClasses = {};
 
   /// The set of all directly instantiated types, that is, the types of the
   /// directly instantiated classes.
   ///
   /// See [_directlyInstantiatedClasses].
-  final Set<InterfaceType> _instantiatedTypes = new Set<InterfaceType>();
+  final Set<InterfaceType> _instantiatedTypes = {};
 
   /// Classes implemented by directly instantiated classes.
-  final Set<ClassEntity> _implementedClasses = new Set<ClassEntity>();
+  final Set<ClassEntity> _implementedClasses = {};
 
-  final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
-      <String, Map<Selector, SelectorConstraints>>{};
-  final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
-      <String, Map<Selector, SelectorConstraints>>{};
-  final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
-      <String, Map<Selector, SelectorConstraints>>{};
+  final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = {};
+  final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = {};
+  final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = {};
 
-  final Map<ClassEntity, ClassUsage> _processedClasses =
-      <ClassEntity, ClassUsage>{};
+  final Map<ClassEntity, ClassUsage> _processedClasses = {};
 
   Map<ClassEntity, ClassUsage> get classUsageForTesting => _processedClasses;
 
   /// Map of registered usage of static and instance members.
-  final Map<MemberEntity, MemberUsage> _memberUsage =
-      <MemberEntity, MemberUsage>{};
+  final Map<MemberEntity, MemberUsage> _memberUsage = {};
 
   /// Map containing instance members of live classes that have not yet been
   /// fully invoked dynamically.
   ///
   /// A method is fully invoked if all is optional parameter have been passed
   /// in some invocation.
-  final Map<String, Set<MemberUsage>> _invokableInstanceMembersByName =
-      <String, Set<MemberUsage>>{};
+  final Map<String, Set<MemberUsage>> _invokableInstanceMembersByName = {};
 
   /// Map containing instance members of live classes that have not yet been
   /// read from dynamically.
-  final Map<String, Set<MemberUsage>> _readableInstanceMembersByName =
-      <String, Set<MemberUsage>>{};
+  final Map<String, Set<MemberUsage>> _readableInstanceMembersByName = {};
 
   /// Map containing instance members of live classes that have not yet been
   /// written to dynamically.
-  final Map<String, Set<MemberUsage>> _writableInstanceMembersByName =
-      <String, Set<MemberUsage>>{};
+  final Map<String, Set<MemberUsage>> _writableInstanceMembersByName = {};
 
-  final Set<DartType> _isChecks = new Set<DartType>();
+  final Set<DartType> _isChecks = {};
 
   final SelectorConstraintsStrategy _selectorConstraintsStrategy;
 
-  final Set<ConstantValue> _constantValues = new Set<ConstantValue>();
+  final Set<ConstantValue> _constantValues = {};
 
-  final Set<DartType> _constTypeLiterals = new Set<DartType>();
-  final Set<DartType> _liveTypeArguments = new Set<DartType>();
+  final Set<DartType> _constTypeLiterals = {};
+  final Set<DartType> _liveTypeArguments = {};
   final Set<TypeVariableType> _namedTypeVariablesNewRti = {};
+  final Set<ClassEntity> _constructorReferences = {};
 
   CodegenWorldBuilderImpl(this._closedWorld, this._selectorConstraintsStrategy,
       this._oneShotInterceptorData);
@@ -226,18 +221,18 @@
 
   Iterable<CallStructure> _getMatchingCallStructures(
       Map<Selector, SelectorConstraints> selectors, MemberEntity member) {
-    if (selectors == null) return const <CallStructure>[];
+    if (selectors == null) return const [];
     Set<CallStructure> callStructures;
     for (Selector selector in selectors.keys) {
       if (selector.appliesUnnamed(member)) {
         SelectorConstraints masks = selectors[selector];
         if (masks.canHit(member, selector.memberName, _closedWorld)) {
-          callStructures ??= new Set<CallStructure>();
+          callStructures ??= {};
           callStructures.add(selector.callStructure);
         }
       }
     }
-    return callStructures ?? const <CallStructure>[];
+    return callStructures ?? const [];
   }
 
   Iterable<CallStructure> _getInvocationCallStructures(MemberEntity member) {
@@ -312,7 +307,7 @@
     String name = selector.name;
     Object constraint = dynamicUse.receiverConstraint;
     Map<Selector, SelectorConstraints> selectors =
-        selectorMap[name] ??= new Maplet<Selector, SelectorConstraints>();
+        selectorMap[name] ??= Maplet<Selector, SelectorConstraints>();
     UniverseSelectorConstraints constraints = selectors[selector];
     if (constraints == null) {
       selectors[selector] = _selectorConstraintsStrategy
@@ -332,7 +327,7 @@
 
   void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
     MemberEntity element = staticUse.element;
-    EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+    EnumSet<MemberUse> useSet = EnumSet<MemberUse>();
     MemberUsage usage = _getMemberUsage(element, useSet);
     switch (staticUse.kind) {
       case StaticUseKind.STATIC_TEAR_OFF:
@@ -395,7 +390,7 @@
             usage.invoke(Accesses.staticAccess, staticUse.callStructure));
         if (staticUse.typeArguments?.isNotEmpty ?? false) {
           registerDynamicInvocation(
-              new Selector.call(member.memberName, staticUse.callStructure),
+              Selector.call(member.memberName, staticUse.callStructure),
               staticUse.typeArguments);
         }
         break;
@@ -425,11 +420,11 @@
       ClassEntity cls, MemberEntity member, MemberUsedCallback memberUsed,
       {bool checkEnqueuerConsistency: false}) {
     if (!member.isInstanceMember) return;
-    EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+    EnumSet<MemberUse> useSet = EnumSet<MemberUse>();
     MemberUsage usage = _getMemberUsage(member, useSet);
     if (useSet.isNotEmpty) {
       if (checkEnqueuerConsistency) {
-        throw new SpannableAssertionFailure(member,
+        throw SpannableAssertionFailure(member,
             'Unenqueued usage of $member: \nbefore: <none>\nafter : $usage');
       } else {
         memberUsed(member, useSet);
@@ -449,7 +444,7 @@
         String memberName = member.name;
         ClassEntity cls = member.enclosingClass;
         bool isNative = _nativeBasicData.isNativeClass(cls);
-        usage = new MemberUsage(member, potentialAccess: potentialAccess);
+        usage = MemberUsage(member, potentialAccess: potentialAccess);
         if (member.isField && !isNative) {
           useSet.addAll(usage.init());
         }
@@ -496,7 +491,7 @@
           }
         }
       } else {
-        usage = new MemberUsage(member, potentialAccess: potentialAccess);
+        usage = MemberUsage(member, potentialAccess: potentialAccess);
         if (member.isField) {
           useSet.addAll(usage.init());
         }
@@ -519,8 +514,8 @@
     // [f] might add elements to [: map[memberName] :] during the loop below
     // so we create a new list for [: map[memberName] :] and prepend the
     // [remaining] members after the loop.
-    map[memberName] = new Set<MemberUsage>();
-    Set<MemberUsage> remaining = new Set<MemberUsage>();
+    map[memberName] = {};
+    Set<MemberUsage> remaining = {};
     for (MemberUsage member in members) {
       if (!f(member)) remaining.add(member);
     }
@@ -529,7 +524,7 @@
 
   /// Return the canonical [ClassUsage] for [cls].
   ClassUsage _getClassUsage(ClassEntity cls) {
-    return _processedClasses.putIfAbsent(cls, () => new ClassUsage(cls));
+    return _processedClasses.putIfAbsent(cls, () => ClassUsage(cls));
   }
 
   void _processInstantiatedClass(ClassEntity cls, ClassUsedCallback classUsed) {
@@ -551,7 +546,7 @@
   }
 
   /// Set of all registered compiled constants.
-  final Set<ConstantValue> _compiledConstants = new Set<ConstantValue>();
+  final Set<ConstantValue> _compiledConstants = {};
 
   Iterable<ConstantValue> get compiledConstantsForTesting => _compiledConstants;
 
@@ -575,6 +570,10 @@
     _liveTypeArguments.add(type);
   }
 
+  void registerConstructorReference(InterfaceType type) {
+    _constructorReferences.add(type.element);
+  }
+
   @override
   CodegenWorld close() {
     Map<MemberEntity, MemberUsage> liveMemberUsage = {};
@@ -583,8 +582,9 @@
         liveMemberUsage[member] = usage;
       }
     });
-    return new CodegenWorldImpl(_closedWorld, liveMemberUsage,
+    return CodegenWorldImpl(_closedWorld, liveMemberUsage,
         constTypeLiterals: _constTypeLiterals,
+        constructorReferences: _constructorReferences,
         directlyInstantiatedClasses: directlyInstantiatedClasses,
         typeVariableTypeLiterals: typeVariableTypeLiterals,
         instantiatedClasses: instantiatedClasses,
@@ -611,6 +611,9 @@
   final Iterable<DartType> constTypeLiterals;
 
   @override
+  final Iterable<ClassEntity> constructorReferences;
+
+  @override
   final Iterable<ClassEntity> directlyInstantiatedClasses;
 
   @override
@@ -648,6 +651,7 @@
 
   CodegenWorldImpl(this._closedWorld, this._liveMemberUsage,
       {this.constTypeLiterals,
+      this.constructorReferences,
       this.directlyInstantiatedClasses,
       this.typeVariableTypeLiterals,
       this.instantiatedClasses,
@@ -728,7 +732,7 @@
   @override
   Iterable<FunctionEntity> get userNoSuchMethods {
     if (_userNoSuchMethodsCache == null) {
-      _userNoSuchMethodsCache = <FunctionEntity>[];
+      _userNoSuchMethodsCache = [];
 
       _liveMemberUsage.forEach((MemberEntity member, MemberUsage memberUsage) {
         if (member is FunctionEntity) {
@@ -862,7 +866,7 @@
   Map<Selector, SelectorConstraints> _asUnmodifiable(
       Map<Selector, SelectorConstraints> map) {
     if (map == null) return null;
-    return new UnmodifiableMapView(map);
+    return UnmodifiableMapView(map);
   }
 
   @override
@@ -884,8 +888,8 @@
   Iterable<ConstantValue> getConstantsForEmission(
       [Comparator<ConstantValue> preSortCompare]) {
     // We must emit dependencies before their uses.
-    Set<ConstantValue> seenConstants = new Set<ConstantValue>();
-    List<ConstantValue> result = new List<ConstantValue>();
+    Set<ConstantValue> seenConstants = {};
+    List<ConstantValue> result = [];
 
     void addConstant(ConstantValue constant) {
       if (!seenConstants.contains(constant)) {
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index cfc28bd..e103bcd 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -53,6 +53,13 @@
         "${_typeArguments?.length ?? 0} were passed.");
   }
 
+  DynamicUse withReceiverConstraint(Object otherReceiverConstraint) {
+    if (otherReceiverConstraint == receiverConstraint) {
+      return this;
+    }
+    return DynamicUse(selector, otherReceiverConstraint, _typeArguments);
+  }
+
   factory DynamicUse.readFromDataSource(DataSource source) {
     source.begin(tag);
     Selector selector = Selector.readFromDataSource(source);
@@ -698,6 +705,7 @@
   INSTANTIATION,
   NATIVE_INSTANTIATION,
   CONST_INSTANTIATION,
+  CONSTRUCTOR_REFERENCE,
   IMPLICIT_CAST,
   PARAMETER_CHECK,
   RTI_VALUE,
@@ -760,6 +768,9 @@
       case TypeUseKind.CONST_INSTANTIATION:
         sb.write('const:');
         break;
+      case TypeUseKind.CONSTRUCTOR_REFERENCE:
+        sb.write('constructor:');
+        break;
       case TypeUseKind.NATIVE_INSTANTIATION:
         sb.write('native:');
         break;
@@ -851,11 +862,9 @@
     return new TypeUse.internal(type, TypeUseKind.RTI_VALUE);
   }
 
-  /// [type] used in a `instanceof` check.
-  factory TypeUse.instanceConstructor(DartType type) {
-    // TODO(johnniwinther,sra): Use a separate use kind if constructors is no
-    // longer used for RTI.
-    return new TypeUse.internal(type, TypeUseKind.RTI_VALUE);
+  /// [type] constructor used, for example in a `instanceof` check.
+  factory TypeUse.constructorReference(DartType type) {
+    return new TypeUse.internal(type, TypeUseKind.CONSTRUCTOR_REFERENCE);
   }
 
   /// [type] used directly as a type argument.
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 5032a42..fc7f564 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -176,6 +176,15 @@
   bool fieldNeverChanges(MemberEntity element);
 
   /// Returns `true` if [selector] on [receiver] can hit a `call` method on a
+  /// subclass of `Closure` using the [abstractValueDomain].
+  ///
+  /// Every implementation of `Closure` has a 'call' method with its own
+  /// signature so it cannot be modelled by a [FunctionEntity]. Also,
+  /// call-methods for tear-off are not part of the element model.
+  bool includesClosureCallInDomain(Selector selector, AbstractValue receiver,
+      AbstractValueDomain abstractValueDomain);
+
+  /// Returns `true` if [selector] on [receiver] can hit a `call` method on a
   /// subclass of `Closure`.
   ///
   /// Every implementation of `Closure` has a 'call' method with its own
@@ -193,6 +202,13 @@
   AbstractValue computeReceiverType(Selector selector, AbstractValue receiver);
 
   /// Returns all the instance members that may be invoked with the [selector]
+  /// on the given [receiver] using the [abstractValueDomain]. The returned elements may include noSuchMethod
+  /// handlers that are potential targets indirectly through the noSuchMethod
+  /// mechanism.
+  Iterable<MemberEntity> locateMembersInDomain(Selector selector,
+      AbstractValue receiver, AbstractValueDomain abstractValueDomain);
+
+  /// Returns all the instance members that may be invoked with the [selector]
   /// on the given [receiver]. The returned elements may include noSuchMethod
   /// handlers that are potential targets indirectly through the noSuchMethod
   /// mechanism.
diff --git a/pkg/compiler/test/jsinterop/declaration_test.dart b/pkg/compiler/test/jsinterop/declaration_test.dart
index 878d20b..0c3a2ce 100644
--- a/pkg/compiler/test/jsinterop/declaration_test.dart
+++ b/pkg/compiler/test/jsinterop/declaration_test.dart
@@ -357,38 +357,6 @@
 
 main() => new A(a: 1);
 '''),
-  const Test('External factory constructor with required parameters.', '''
-@JS()
-library test;
-
-import 'package:js/js.dart';
-
-@JS()
-@anonymous
-class A {
-  external factory A(a, b);
-}
-
-main() => new A(1, 2);
-''', errors: const [
-    MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS
-  ]),
-  const Test('External factory constructor with optional parameters.', '''
-@JS()
-library test;
-
-import 'package:js/js.dart';
-
-@JS()
-@anonymous
-class A {
-  external factory A([a, b]);
-}
-
-main() => new A(1);
-''', errors: const [
-    MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS
-  ]),
   const Test('Function-typed return type', '''
 @JS()
 library lib;
diff --git a/pkg/compiler/test/rti/emission/arguments.dart b/pkg/compiler/test/rti/emission/arguments.dart
index 215e20c..7089270 100644
--- a/pkg/compiler/test/rti/emission/arguments.dart
+++ b/pkg/compiler/test/rti/emission/arguments.dart
@@ -4,10 +4,10 @@
 
 // @dart = 2.7
 
-/*class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*class: B:checks=[],typeArgument*/
+/*class: B:checks=[],onlyForRti,typeArgument*/
 class B {}
 
 /*class: C:checkedInstance,checks=[],instance*/
diff --git a/pkg/compiler/test/rti/emission/dynamic_instance.dart b/pkg/compiler/test/rti/emission/dynamic_instance.dart
index 0f3a503..14284f7 100644
--- a/pkg/compiler/test/rti/emission/dynamic_instance.dart
+++ b/pkg/compiler/test/rti/emission/dynamic_instance.dart
@@ -6,7 +6,7 @@
 
 import 'package:expect/expect.dart';
 
-/*class: B:checkedInstance,checks=[],typeArgument*/
+/*class: B:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class B {}
 
 /*class: C:checks=[],instance*/
diff --git a/pkg/compiler/test/rti/emission/dynamic_type_argument.dart b/pkg/compiler/test/rti/emission/dynamic_type_argument.dart
index 6837723..5da881f 100644
--- a/pkg/compiler/test/rti/emission/dynamic_type_argument.dart
+++ b/pkg/compiler/test/rti/emission/dynamic_type_argument.dart
@@ -9,7 +9,7 @@
 /*class: A:checkedInstance,checks=[],instance*/
 class A<T> {}
 
-/*class: B:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B {}
 
 /*class: C:checks=[],instance*/
@@ -21,10 +21,10 @@
   method2<T>() => new A<T>();
 }
 
-/*class: D:checks=[],typeArgument*/
+/*class: D:checks=[],onlyForRti,typeArgument*/
 class D extends B {}
 
-/*class: E:checks=[],typeArgument*/
+/*class: E:checks=[],onlyForRti,typeArgument*/
 class E {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/dynamic_type_literal.dart b/pkg/compiler/test/rti/emission/dynamic_type_literal.dart
index 0d26a10..a635a06 100644
--- a/pkg/compiler/test/rti/emission/dynamic_type_literal.dart
+++ b/pkg/compiler/test/rti/emission/dynamic_type_literal.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*class: global#Type:checks=[],instance,typeLiteral*/
+/*class: global#Type:checks=[],instance,onlyForRti,typeLiteral*/
 
 import "package:expect/expect.dart";
 
diff --git a/pkg/compiler/test/rti/emission/fixed_type_argument.dart b/pkg/compiler/test/rti/emission/fixed_type_argument.dart
index c00f5bf..5ae24b0 100644
--- a/pkg/compiler/test/rti/emission/fixed_type_argument.dart
+++ b/pkg/compiler/test/rti/emission/fixed_type_argument.dart
@@ -4,12 +4,12 @@
 
 // @dart = 2.7
 
-/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*spec.class: B:checkedInstance,checks=[$isA],typeArgument*/
-/*prod.class: B:checks=[$isA],typeArgument*/
+/*spec.class: B:checkedInstance,checks=[$isA],onlyForRti,typeArgument*/
+/*prod.class: B:checks=[$isA],onlyForRti,typeArgument*/
 class B implements A {}
 
 /*class: C:checks=[],indirectInstance*/
diff --git a/pkg/compiler/test/rti/emission/fixed_type_argument_implements.dart b/pkg/compiler/test/rti/emission/fixed_type_argument_implements.dart
index 29590c5..a6a9c1b 100644
--- a/pkg/compiler/test/rti/emission/fixed_type_argument_implements.dart
+++ b/pkg/compiler/test/rti/emission/fixed_type_argument_implements.dart
@@ -7,11 +7,11 @@
 // Test that we emit the relation between B and A even when B is only live
 // as a type argument through the supertype of D.
 
-/*spec.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*spec.class: B:checks=[$isA],typeArgument*/
-/*prod.class: B:checks=[],typeArgument*/
+/*spec.class: B:checks=[$isA],onlyForRti,typeArgument*/
+/*prod.class: B:checks=[],onlyForRti,typeArgument*/
 class B implements A {}
 
 /*spec.class: C:checkedInstance*/
diff --git a/pkg/compiler/test/rti/emission/function_typed_arguments.dart b/pkg/compiler/test/rti/emission/function_typed_arguments.dart
index 58d5f14..69e8ad7 100644
--- a/pkg/compiler/test/rti/emission/function_typed_arguments.dart
+++ b/pkg/compiler/test/rti/emission/function_typed_arguments.dart
@@ -18,10 +18,10 @@
   test6();
 }
 
-/*class: B1:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B1<T> {}
 
-/*class: C1:checkedTypeArgument,checks=[],typeArgument*/
+/*class: C1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class C1 extends B1<int> {}
 
 @pragma('dart2js:noInline')
@@ -34,10 +34,10 @@
 @pragma('dart2js:noInline')
 _test1(f) => f is A<void Function(C1)>;
 
-/*class: B2:checks=[],typeArgument*/
+/*class: B2:checks=[],onlyForRti,typeArgument*/
 class B2<T> {}
 
-/*class: C2:checkedTypeArgument,checks=[],typeArgument*/
+/*class: C2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class C2 extends B2<int> {}
 
 @pragma('dart2js:noInline')
@@ -50,10 +50,10 @@
 @pragma('dart2js:noInline')
 _test2(f) => f is A<C2 Function()>;
 
-/*class: B3:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B3<T> {}
 
-/*class: C3:checkedTypeArgument,checks=[],typeArgument*/
+/*class: C3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class C3 extends B3<int> {}
 
 @pragma('dart2js:noInline')
@@ -66,10 +66,10 @@
 @pragma('dart2js:noInline')
 _test3(f) => f is A<void Function(B3<int>)>;
 
-/*class: B4:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B4:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B4<T> {}
 
-/*class: C4:checks=[],typeArgument*/
+/*class: C4:checks=[],onlyForRti,typeArgument*/
 class C4 extends B4<int> {}
 
 @pragma('dart4js:noInline')
@@ -82,10 +82,10 @@
 @pragma('dart4js:noInline')
 _test4(f) => f is A<B4<int> Function()>;
 
-/*class: B5:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B5:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B5<T> {}
 
-/*class: C5:checkedTypeArgument,checks=[],typeArgument*/
+/*class: C5:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class C5 extends B5<int> {}
 
 @pragma('dart2js:noInline')
@@ -98,10 +98,10 @@
 @pragma('dart2js:noInline')
 _test5(f) => f is A<void Function(C5 Function())>;
 
-/*class: B6:checks=[],typeArgument*/
+/*class: B6:checks=[],onlyForRti,typeArgument*/
 class B6<T> {}
 
-/*class: C6:checkedTypeArgument,checks=[],typeArgument*/
+/*class: C6:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class C6 extends B6<int> {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/future_or_as_type_argument.dart b/pkg/compiler/test/rti/emission/future_or_as_type_argument.dart
index 2b718e3..9b2fcd45 100644
--- a/pkg/compiler/test/rti/emission/future_or_as_type_argument.dart
+++ b/pkg/compiler/test/rti/emission/future_or_as_type_argument.dart
@@ -6,15 +6,15 @@
 
 import 'dart:async';
 
-/*class: global#Future:checks=[],typeArgument*/
+/*class: global#Future:checks=[],onlyForRti,typeArgument*/
 
 /*class: A:checkedInstance,checks=[],instance*/
 class A<T> {}
 
-/*class: B:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B {}
 
-/*class: C:checks=[],typeArgument*/
+/*class: C:checks=[],onlyForRti,typeArgument*/
 class C {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/future_or_future_or_generic.dart b/pkg/compiler/test/rti/emission/future_or_future_or_generic.dart
index db1eceb..989c8de 100644
--- a/pkg/compiler/test/rti/emission/future_or_future_or_generic.dart
+++ b/pkg/compiler/test/rti/emission/future_or_future_or_generic.dart
@@ -18,10 +18,10 @@
 /*class: B:checkedInstance,checkedTypeArgument,checks=[],instance,typeArgument*/
 class B<T> {}
 
-/*class: C:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*class: C:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class C {}
 
-/*class: D:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*class: D:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class D {}
 
 main() {
diff --git a/pkg/compiler/test/rti/emission/future_or_generic.dart b/pkg/compiler/test/rti/emission/future_or_generic.dart
index 95dd12f..c4ece54 100644
--- a/pkg/compiler/test/rti/emission/future_or_generic.dart
+++ b/pkg/compiler/test/rti/emission/future_or_generic.dart
@@ -20,7 +20,7 @@
 
 // TODO(johnniwinther): Do we need the implied `checkedTypeArgument` from
 // the `Future<C>` test in `A.m`?
-/*class: C:checkedInstance,checks=[],typeArgument*/
+/*class: C:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class C {}
 
 /*class: FutureMock:checks=[$isFuture],instance*/
diff --git a/pkg/compiler/test/rti/emission/future_or_generic2.dart b/pkg/compiler/test/rti/emission/future_or_generic2.dart
index bd21431..5fa8720 100644
--- a/pkg/compiler/test/rti/emission/future_or_generic2.dart
+++ b/pkg/compiler/test/rti/emission/future_or_generic2.dart
@@ -18,10 +18,10 @@
 /*class: B:checkedInstance,checkedTypeArgument,checks=[],instance,typeArgument*/
 class B<T> {}
 
-/*class: C:checkedInstance,checks=[],typeArgument*/
+/*class: C:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class C {}
 
-/*class: D:checkedInstance,checks=[],typeArgument*/
+/*class: D:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class D {}
 
 main() {
diff --git a/pkg/compiler/test/rti/emission/future_or_type_argument.dart b/pkg/compiler/test/rti/emission/future_or_type_argument.dart
index e5db913..c225b61 100644
--- a/pkg/compiler/test/rti/emission/future_or_type_argument.dart
+++ b/pkg/compiler/test/rti/emission/future_or_type_argument.dart
@@ -7,15 +7,15 @@
 import 'dart:async';
 import 'package:expect/expect.dart';
 
-/*class: global#Future:checks=[],typeArgument*/
+/*class: global#Future:checks=[],onlyForRti,typeArgument*/
 
 /*class: A:checkedInstance,checks=[],instance*/
 class A<T> {}
 
-/*class: B:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B {}
 
-/*class: C:checks=[],typeArgument*/
+/*class: C:checks=[],onlyForRti,typeArgument*/
 class C {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/generic_instanceof4.dart b/pkg/compiler/test/rti/emission/generic_instanceof4.dart
index c228394..48b6274 100644
--- a/pkg/compiler/test/rti/emission/generic_instanceof4.dart
+++ b/pkg/compiler/test/rti/emission/generic_instanceof4.dart
@@ -12,7 +12,7 @@
   }
 }
 
-/*class: BB:checkedInstance,checks=[],typeArgument*/
+/*class: BB:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class BB {}
 
 /*class: B:checks=[$isBB],instance*/
diff --git a/pkg/compiler/test/rti/emission/generic_methods_dynamic_02.dart b/pkg/compiler/test/rti/emission/generic_methods_dynamic_02.dart
index fa58b35..c4db1f9 100644
--- a/pkg/compiler/test/rti/emission/generic_methods_dynamic_02.dart
+++ b/pkg/compiler/test/rti/emission/generic_methods_dynamic_02.dart
@@ -8,7 +8,7 @@
 
 library generic_methods_dynamic_test;
 
-/*spec.class: A:checkedInstance,checks=[],typeArgument*/
+/*spec.class: A:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class A {}
 
 /*spec.class: B:checks=[],instance*/
diff --git a/pkg/compiler/test/rti/emission/indirect_through_static.dart b/pkg/compiler/test/rti/emission/indirect_through_static.dart
index 8246072..848e578 100644
--- a/pkg/compiler/test/rti/emission/indirect_through_static.dart
+++ b/pkg/compiler/test/rti/emission/indirect_through_static.dart
@@ -4,10 +4,10 @@
 
 // @dart = 2.7
 
-/*class: A:checkedInstance,checks=[],typeArgument*/
+/*class: A:checkedInstance,checks=[],onlyForRti,typeArgument*/
 abstract class A {}
 
-/*class: B:checks=[$isA],typeArgument*/
+/*class: B:checks=[$isA],onlyForRti,typeArgument*/
 class B implements A {}
 
 /*class: C:checkedInstance,checks=[],instance,typeArgument*/
diff --git a/pkg/compiler/test/rti/emission/jsinterop.dart b/pkg/compiler/test/rti/emission/jsinterop.dart
index 422ece1..f88db92 100644
--- a/pkg/compiler/test/rti/emission/jsinterop.dart
+++ b/pkg/compiler/test/rti/emission/jsinterop.dart
@@ -11,33 +11,33 @@
 
 import 'package:js/js.dart';
 
-/*class: A:checkedInstance,checks=[],instance*/
+/*class: A:checkedInstance,checks=[],instance,onlyForRti*/
 @JS()
 class A {
   external A();
 }
 
-/*class: B:checks=[],instance*/
+/*class: B:checks=[],instance,onlyForRti*/
 @JS('BClass')
 class B {
   external B();
 }
 
-/*class: C:checkedInstance,checks=[],instance*/
+/*class: C:checkedInstance,checks=[],instance,onlyForRti*/
 @JS()
 @anonymous
 class C {
   external factory C();
 }
 
-/*class: D:checks=[],instance*/
+/*class: D:checks=[],instance,onlyForRti*/
 @JS()
 @anonymous
 class D {
   external factory D();
 }
 
-/*class: E:checks=[],instance,typeLiteral*/
+/*class: E:checks=[],instance*/
 class E {
   E();
 }
diff --git a/pkg/compiler/test/rti/emission/jsinterop_generic.dart b/pkg/compiler/test/rti/emission/jsinterop_generic.dart
index 60ab4ae..cc2d44a 100644
--- a/pkg/compiler/test/rti/emission/jsinterop_generic.dart
+++ b/pkg/compiler/test/rti/emission/jsinterop_generic.dart
@@ -16,7 +16,7 @@
 import 'package:expect/expect.dart';
 import 'package:js/js.dart';
 
-/*class: A:checkedInstance,checks=[],instance*/
+/*class: A:checkedInstance,checks=[],instance,onlyForRti*/
 @JS()
 @anonymous
 class A<T> {
@@ -26,7 +26,7 @@
 /*class: B:checkedInstance*/
 class B<T> {}
 
-/*class: C:checks=[],instance*/
+/*class: C:checks=[],instance,onlyForRti*/
 @JS()
 @anonymous
 class C implements B<int> {
@@ -36,7 +36,7 @@
 /*class: D:checkedInstance*/
 class D<T> {}
 
-/*class: E:checks=[],instance*/
+/*class: E:checks=[],instance,onlyForRti*/
 @JS()
 @anonymous
 class E implements B<String> {
diff --git a/pkg/compiler/test/rti/emission/jsinterop_generic_factory_args.dart b/pkg/compiler/test/rti/emission/jsinterop_generic_factory_args.dart
index 2815d96..c7dc08b 100644
--- a/pkg/compiler/test/rti/emission/jsinterop_generic_factory_args.dart
+++ b/pkg/compiler/test/rti/emission/jsinterop_generic_factory_args.dart
@@ -4,20 +4,18 @@
 
 // @dart = 2.7
 
-// dart2jsOptions=--strong
-
 @JS()
 library foo;
 
-/*class: global#JavaScriptObject:checks=[$isA]*/
+/*class: global#JavaScriptObject:checks=[$isA],onlyForRti*/
 
 import 'package:expect/expect.dart';
 import 'package:js/js.dart';
 
 @JS()
 @anonymous
-/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A<T> {
   external factory A();
 }
diff --git a/pkg/compiler/test/rti/emission/list.dart b/pkg/compiler/test/rti/emission/list.dart
index 329b67d..5c1199c 100644
--- a/pkg/compiler/test/rti/emission/list.dart
+++ b/pkg/compiler/test/rti/emission/list.dart
@@ -9,12 +9,12 @@
 
 /*class: global#Iterable:checkedInstance*/
 
-/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*spec.class: B:checkedInstance,checks=[],typeArgument*/
-/*prod.class: B:checks=[],typeArgument*/
+/*spec.class: B:checkedInstance,checks=[],onlyForRti,typeArgument*/
+/*prod.class: B:checks=[],onlyForRti,typeArgument*/
 class B {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/map_literal.dart b/pkg/compiler/test/rti/emission/map_literal.dart
index 6200e67..b89ceec 100644
--- a/pkg/compiler/test/rti/emission/map_literal.dart
+++ b/pkg/compiler/test/rti/emission/map_literal.dart
@@ -9,7 +9,7 @@
 /*class: global#LinkedHashMap:*/
 /*class: global#JsLinkedHashMap:checks=[],instance*/
 
-/*spec.class: global#double:checkedInstance,checks=[],instance,typeArgument*/
+/*spec.class: global#double:checkedInstance,checks=[],instance,onlyForRti,typeArgument*/
 
 /*class: global#JSDouble:checks=[],instance*/
 
diff --git a/pkg/compiler/test/rti/emission/mixin_subtype.dart b/pkg/compiler/test/rti/emission/mixin_subtype.dart
index 168c6da..adf0e05 100644
--- a/pkg/compiler/test/rti/emission/mixin_subtype.dart
+++ b/pkg/compiler/test/rti/emission/mixin_subtype.dart
@@ -12,19 +12,19 @@
 
 // A mixin with multiple super-types and implemented types.
 
-/*class: A:checkedInstance,checks=[],typeArgument*/
+/*class: A:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*class: B:checkedInstance,checks=[],typeArgument*/
+/*class: B:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class B {}
 
-/*class: I:checkedInstance,checks=[],typeArgument*/
+/*class: I:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class I {}
 
-/*class: J:checkedInstance,checks=[],typeArgument*/
+/*class: J:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class J {}
 
-/*class: M1:checkedInstance,checks=[$isA,$isB,$isI,$isJ],typeArgument*/
+/*class: M1:checkedInstance,checks=[$isA,$isB,$isI,$isJ],onlyForRti,typeArgument*/
 mixin M1 on A, B implements I, J {}
 
 /*class: M2:checkedInstance,checks=[$isA,$isB,$isI,$isJ],typeArgument*/
@@ -42,13 +42,13 @@
 /*class: C:checkedInstance,checks=[$isA,$isB],indirectInstance,typeArgument*/
 class C implements A, B {}
 
-/*class: D1:checkedInstance,checks=[$isI,$isJ,$isM1],typeArgument*/
+/*class: D1:checkedInstance,checks=[$isI,$isJ,$isM1],onlyForRti,typeArgument*/
 class D1 = C with M1;
 
 /*class: D2:checkedInstance,checks=[$isI,$isJ],instance,typeArgument*/
 class D2 = C with M2;
 
-/*class: D3:checkedInstance,checks=[$isI,$isJ,$isM3],typeArgument*/
+/*class: D3:checkedInstance,checks=[$isI,$isJ,$isM3],onlyForRti,typeArgument*/
 class D3 = C with M3;
 
 /*class: D4:checkedInstance,checks=[$isI,$isJ],instance,typeArgument*/
@@ -61,25 +61,25 @@
 class E5 extends D5 {}
 
 // Same, with generics.
-/*class: GA:checkedInstance,checks=[],typeArgument*/
+/*class: GA:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class GA<T> {}
 
-/*class: GB:checkedInstance,checks=[],typeArgument*/
+/*class: GB:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class GB<T> {}
 
-/*class: GI:checkedInstance,checks=[],typeArgument*/
+/*class: GI:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class GI<T> {}
 
-/*class: GJ:checkedInstance,checks=[],typeArgument*/
+/*class: GJ:checkedInstance,checks=[],onlyForRti,typeArgument*/
 class GJ<T> {}
 
-/*class: GM:checkedInstance,checks=[$isGA,$isGB,$isGI,$isGJ],typeArgument*/
+/*class: GM:checkedInstance,checks=[$isGA,$isGB,$isGI,$isGJ],onlyForRti,typeArgument*/
 mixin GM<T> on GA<T>, GB<List<T>> implements GI<Iterable<T>>, GJ<Set<T>> {}
 
-/*class: GC:checkedInstance,checks=[$isGA,$isGB],typeArgument*/
+/*class: GC:checkedInstance,checks=[$isGA,$isGB],onlyForRti,typeArgument*/
 class GC<T> implements GA<T>, GB<List<T>> {}
 
-/*class: GD:checkedInstance,checks=[$isGI,$isGJ,$isGM],typeArgument*/
+/*class: GD:checkedInstance,checks=[$isGI,$isGJ,$isGM],onlyForRti,typeArgument*/
 class GD<T> = GC<T> with GM<T>;
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/mixin_type_arguments.dart b/pkg/compiler/test/rti/emission/mixin_type_arguments.dart
index 8a62cab..dd2a28b 100644
--- a/pkg/compiler/test/rti/emission/mixin_type_arguments.dart
+++ b/pkg/compiler/test/rti/emission/mixin_type_arguments.dart
@@ -6,22 +6,22 @@
 
 import 'package:expect/expect.dart' show Expect;
 
-/*class: A:checks=[],typeArgument*/
+/*class: A:checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*class: B:checks=[],typeArgument*/
+/*class: B:checks=[],onlyForRti,typeArgument*/
 class B {}
 
-/*class: C:checks=[],typeArgument*/
+/*class: C:checks=[],onlyForRti,typeArgument*/
 class C {}
 
-/*class: D:checks=[],typeArgument*/
+/*class: D:checks=[],onlyForRti,typeArgument*/
 class D {}
 
-/*class: E:checks=[],typeArgument*/
+/*class: E:checks=[],onlyForRti,typeArgument*/
 class E {}
 
-/*class: F:checks=[],typeArgument*/
+/*class: F:checks=[],onlyForRti,typeArgument*/
 class F {}
 
 /*class: M1:checks=[]*/
diff --git a/pkg/compiler/test/rti/emission/optimized_is_check.dart b/pkg/compiler/test/rti/emission/optimized_is_check.dart
new file mode 100644
index 0000000..ca84289
--- /dev/null
+++ b/pkg/compiler/test/rti/emission/optimized_is_check.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2020, 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.
+
+// @dart = 2.7
+
+// It is sometimes possible to compile is-checks to 'instanceof', when the class
+// is not in an 'implements' clause or used as a mixin.
+
+// This test verifies is-checks work with simple classes that have various
+// degrees of instantiation.
+
+/*class: Instantiated:checkedInstance,checks=[],instance,typeArgument*/
+class Instantiated {} // instantiated and used in many ways
+
+/*class: Deferred:checks=[],instance*/
+class Deferred {} // instantiated after first check
+
+class Unused {} // used only in is-check
+
+/*class: Removed:checks=[],onlyForConstructor*/
+class Removed {} // allocated but optimized out of program
+
+/*class: DeferredAndRemoved:checks=[],onlyForConstructor*/
+class DeferredAndRemoved {} // allocated after first check and removed
+
+/*class: UsedAsTypeParameter:checkedInstance,checks=[],onlyForRti,typeArgument*/
+class UsedAsTypeParameter {} // only used as a type parameter
+
+/*class: UsedAsTestedTypeParameter:checkedInstance,checks=[],onlyForRti,typeArgument*/
+class UsedAsTestedTypeParameter {} // only used as a type parameter
+
+/*class: Check:checks=[],instance*/
+class Check<T> {
+  bool check(x) => x is T;
+}
+
+class Check2<T> {
+  bool check(x) => x is UsedAsTypeParameter;
+}
+
+void main() {
+  var things = List(3);
+  things.setRange(0, 3, [Instantiated(), 1, Object()]);
+
+  var checkX = Check<Instantiated>();
+  var checkU1 = Check<UsedAsTestedTypeParameter>();
+  var checkU2 = Check<UsedAsTypeParameter>();
+
+  // ignore: UNUSED_LOCAL_VARIABLE
+  var removed = Removed(); // This is optimized out.
+
+  // Tests that can be compiled to instanceof:
+  if (things[0] is Instantiated) print('expected');
+  if (things[1] is Instantiated) print('unexpected');
+  if (things[1] is Removed) print('unexpected');
+  if (things[1] is DeferredAndRemoved) print('unexpected');
+  if (things[1] is Deferred) print('unexpected');
+  // Tests that might be optimized to false since there are no allocations:
+  if (things[1] is Unused) print('unexpected');
+  if (things[1] is UsedAsTypeParameter) print('unexpected');
+
+  if (checkX.check(things[0])) print('expected');
+  if (checkX.check(things[1])) print('unexpected');
+  if (checkU1.check(things[1])) print('unexpected');
+  if (checkU2.check(things[1])) print('unexpected');
+
+  // ignore: UNUSED_LOCAL_VARIABLE
+  var removed2 = DeferredAndRemoved(); // This is optimized out.
+
+  // First allocation of Deferred is after the above tests.
+  things.setRange(0, 3, [Instantiated(), 1, Deferred()]);
+
+  // Tests that can be compiled to instanceof:
+  if (things[0] is Instantiated) print('expected');
+  if (things[1] is Instantiated) print('unexpected');
+  if (things[1] is Removed) print('unexpected');
+  if (things[1] is DeferredAndRemoved) print('unexpected');
+  if (things[1] is Deferred) print('unexpected');
+  if (things[2] is Deferred) print('expected');
+  // Tests that might be optimized to false since there are no allocations:
+  if (things[1] is Unused) print('unexpected');
+  if (things[1] is UsedAsTypeParameter) print('unexpected');
+}
diff --git a/pkg/compiler/test/rti/emission/replaced_type_variable.dart b/pkg/compiler/test/rti/emission/replaced_type_variable.dart
index 6d75642..78ae756 100644
--- a/pkg/compiler/test/rti/emission/replaced_type_variable.dart
+++ b/pkg/compiler/test/rti/emission/replaced_type_variable.dart
@@ -14,7 +14,7 @@
   Type get type => T;
 }
 
-/*class: A:checks=[],typeArgument*/
+/*class: A:checks=[],onlyForRti,typeArgument*/
 class A {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/runtime_type.dart b/pkg/compiler/test/rti/emission/runtime_type.dart
index 2d2b913..ea9d7cc 100644
--- a/pkg/compiler/test/rti/emission/runtime_type.dart
+++ b/pkg/compiler/test/rti/emission/runtime_type.dart
@@ -7,7 +7,7 @@
 /*class: A:checks=[],instance*/
 class A<T> {}
 
-/*class: B:checks=[],typeArgument*/
+/*class: B:checks=[],onlyForRti,typeArgument*/
 class B<T> {}
 
 main() {
diff --git a/pkg/compiler/test/rti/emission/self.dart b/pkg/compiler/test/rti/emission/self.dart
index bab2585..90d65cb 100644
--- a/pkg/compiler/test/rti/emission/self.dart
+++ b/pkg/compiler/test/rti/emission/self.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*class: C:checks=[],instance,typeLiteral*/
+/*class: C:checks=[],instance*/
 class C {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/subtype_named_args.dart b/pkg/compiler/test/rti/emission/subtype_named_args.dart
index 5ae613b..d94bedf 100644
--- a/pkg/compiler/test/rti/emission/subtype_named_args.dart
+++ b/pkg/compiler/test/rti/emission/subtype_named_args.dart
@@ -8,32 +8,32 @@
 
 import 'package:expect/expect.dart';
 
-/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*spec.class: A1:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A1:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A1:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A1 {}
 
-/*spec.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A2:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A2 {}
 
-/*spec.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
-/*prod.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],typeArgument*/
+/*spec.class: B:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2],onlyForRti,typeArgument*/
+/*prod.class: B:checkedTypeArgument,checks=[$isA,$isA1,$isA2],onlyForRti,typeArgument*/
 class B implements A, A1, A2 {}
 
-/*spec.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
-/*prod.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],typeArgument*/
+/*spec.class: C:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],onlyForRti,typeArgument*/
+/*prod.class: C:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB],onlyForRti,typeArgument*/
 class C implements B {}
 
-/*spec.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
-/*prod.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],typeArgument*/
+/*spec.class: D:checkedInstance,checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],onlyForRti,typeArgument*/
+/*prod.class: D:checkedTypeArgument,checks=[$isA,$isA1,$isA2,$isB,$isC],onlyForRti,typeArgument*/
 class D implements C {}
 
-/*spec.class: G:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: G:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: G:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: G:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class G<T, S, U, W> {}
 
 typedef classesFunc({A a, B b, C c, D d});
diff --git a/pkg/compiler/test/rti/emission/superclass.dart b/pkg/compiler/test/rti/emission/superclass.dart
index 74aa29f..8426d4f 100644
--- a/pkg/compiler/test/rti/emission/superclass.dart
+++ b/pkg/compiler/test/rti/emission/superclass.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*class: B:checks=[],indirectInstance,typeLiteral*/
+/*class: B:checks=[],indirectInstance*/
 class B {}
 
 /*class: C:checks=[],instance*/
diff --git a/pkg/compiler/test/rti/emission/superclass_complex.dart b/pkg/compiler/test/rti/emission/superclass_complex.dart
index 4513fda..adc95a3 100644
--- a/pkg/compiler/test/rti/emission/superclass_complex.dart
+++ b/pkg/compiler/test/rti/emission/superclass_complex.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A<T> {}
 
 /*class: B:checkedInstance,checks=[],indirectInstance*/
diff --git a/pkg/compiler/test/rti/emission/superclass_supertype_complex.dart b/pkg/compiler/test/rti/emission/superclass_supertype_complex.dart
index b6a325b..0601bc9 100644
--- a/pkg/compiler/test/rti/emission/superclass_supertype_complex.dart
+++ b/pkg/compiler/test/rti/emission/superclass_supertype_complex.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A<T> {}
 
 /*class: B:checkedInstance*/
diff --git a/pkg/compiler/test/rti/emission/supertype_complex.dart b/pkg/compiler/test/rti/emission/supertype_complex.dart
index d51cf38..c8e26ec 100644
--- a/pkg/compiler/test/rti/emission/supertype_complex.dart
+++ b/pkg/compiler/test/rti/emission/supertype_complex.dart
@@ -4,7 +4,7 @@
 
 // @dart = 2.7
 
-/*class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A<T> {}
 
 /*class: B:checkedInstance*/
diff --git a/pkg/compiler/test/rti/emission/tear_off_types.dart b/pkg/compiler/test/rti/emission/tear_off_types.dart
index a47eaa7..14ac56a 100644
--- a/pkg/compiler/test/rti/emission/tear_off_types.dart
+++ b/pkg/compiler/test/rti/emission/tear_off_types.dart
@@ -16,10 +16,10 @@
   test7();
 }
 
-/*class: A1:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A1:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A1<T> {}
 
-/*class: B1:checks=[],typeArgument*/
+/*class: B1:checks=[],onlyForRti,typeArgument*/
 class B1 extends A1<int> {}
 
 @pragma('dart2js:noInline')
@@ -36,12 +36,12 @@
 @pragma('dart2js:noInline')
 bool _test1(f) => f is A1<int> Function();
 
-/*spec.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A2:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A2<T> {}
 
-/*spec.class: B2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: B2:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: B2:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: B2:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B2 extends A2<int> {}
 
 @pragma('dart2js:noInline')
@@ -58,12 +58,12 @@
 @pragma('dart2js:noInline')
 bool _test2(f) => f is void Function(A2<int>);
 
-/*spec.class: A3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: A3:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: A3:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: A3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A3<T> {}
 
-/*spec.class: B3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
-/*prod.class: B3:checkedTypeArgument,checks=[],typeArgument*/
+/*spec.class: B3:checkedInstance,checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
+/*prod.class: B3:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B3 extends A3<int> {}
 
 @pragma('dart3js:noInline')
@@ -80,10 +80,10 @@
 @pragma('dart3js:noInline')
 _test3(f) => f is void Function(B3);
 
-/*class: A4:checks=[],typeArgument*/
+/*class: A4:checks=[],onlyForRti,typeArgument*/
 class A4<T> {}
 
-/*class: B4:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B4:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B4 extends A4<int> {}
 
 @pragma('dart4js:noInline')
@@ -100,10 +100,10 @@
 @pragma('dart4js:noInline')
 _test4(f) => f is B4 Function();
 
-/*class: A5:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A5:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A5<T> {}
 
-/*class: B5:checks=[],typeArgument*/
+/*class: B5:checks=[],onlyForRti,typeArgument*/
 class B5 extends A5<int> {}
 
 @pragma('dart2js:noInline')
@@ -120,10 +120,10 @@
 @pragma('dart2js:noInline')
 bool _test5(f) => f is void Function(void Function(A5<int>));
 
-/*class: A6:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A6:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A6<T> {}
 
-/*class: B6:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B6:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B6 extends A6<int> {}
 
 @pragma('dart6js:noInline')
@@ -140,10 +140,10 @@
 @pragma('dart6js:noInline')
 _test6(f) => f is void Function(B6) Function();
 
-/*class: A7:checks=[],typeArgument*/
+/*class: A7:checks=[],onlyForRti,typeArgument*/
 class A7<T> {}
 
-/*class: B7:checkedTypeArgument,checks=[],typeArgument*/
+/*class: B7:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class B7 extends A7<int> {}
 
 @pragma('dart7js:noInline')
diff --git a/pkg/compiler/test/rti/emission/type_argument_dynamic.dart b/pkg/compiler/test/rti/emission/type_argument_dynamic.dart
index 8ff02c5..0fb3030 100644
--- a/pkg/compiler/test/rti/emission/type_argument_dynamic.dart
+++ b/pkg/compiler/test/rti/emission/type_argument_dynamic.dart
@@ -6,16 +6,16 @@
 
 import 'package:expect/expect.dart';
 
-/*class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*class: B:checks=[$isA],typeArgument*/
+/*class: B:checks=[$isA],onlyForRti,typeArgument*/
 class B implements A {}
 
 /*class: C:checkedInstance,checks=[],instance*/
 class C<T> {}
 
-/*class: D:checks=[],typeArgument*/
+/*class: D:checks=[],onlyForRti,typeArgument*/
 class D {}
 
 /*class: E:checks=[],instance*/
diff --git a/pkg/compiler/test/rti/emission/type_argument_static.dart b/pkg/compiler/test/rti/emission/type_argument_static.dart
index d4d889b..cf1ea59 100644
--- a/pkg/compiler/test/rti/emission/type_argument_static.dart
+++ b/pkg/compiler/test/rti/emission/type_argument_static.dart
@@ -6,16 +6,16 @@
 
 import 'package:expect/expect.dart';
 
-/*class: A:checkedTypeArgument,checks=[],typeArgument*/
+/*class: A:checkedTypeArgument,checks=[],onlyForRti,typeArgument*/
 class A {}
 
-/*class: B:checks=[$isA],typeArgument*/
+/*class: B:checks=[$isA],onlyForRti,typeArgument*/
 class B implements A {}
 
 /*class: C:checkedInstance,checks=[],instance*/
 class C<T> {}
 
-/*class: D:checks=[],typeArgument*/
+/*class: D:checks=[],onlyForRti,typeArgument*/
 class D {}
 
 @pragma('dart2js:noInline')
diff --git a/pkg/compiler/test/rti/emission/type_literal.dart b/pkg/compiler/test/rti/emission/type_literal.dart
index f14bb65..b49f32f 100644
--- a/pkg/compiler/test/rti/emission/type_literal.dart
+++ b/pkg/compiler/test/rti/emission/type_literal.dart
@@ -6,10 +6,10 @@
 
 import 'package:expect/expect.dart';
 
-/*class: Class1:checks=[],typeLiteral*/
+/*class: Class1:checks=[],onlyForRti,typeLiteral*/
 class Class1 {}
 
-/*class: Class2:checks=[],typeLiteral*/
+/*class: Class2:checks=[],onlyForRti,typeLiteral*/
 class Class2<X> {}
 
 void main() {
diff --git a/pkg/compiler/test/rti/rti_emission_test_helper.dart b/pkg/compiler/test/rti/rti_emission_test_helper.dart
index 107c597..3cca1c5 100644
--- a/pkg/compiler/test/rti/rti_emission_test_helper.dart
+++ b/pkg/compiler/test/rti/rti_emission_test_helper.dart
@@ -37,6 +37,8 @@
   static const String isChecks = 'checks';
   static const String indirectInstance = 'indirectInstance';
   static const String directInstance = 'instance';
+  static const String onlyForRti = 'onlyForRti';
+  static const String onlyForConstructor = 'onlyForConstructor';
   static const String checkedInstance = 'checkedInstance';
   static const String typeArgument = 'typeArgument';
   static const String checkedTypeArgument = 'checkedTypeArgument';
@@ -65,6 +67,12 @@
       if (cls.functionTypeIndex != null) {
         features.add(Tags.functionType);
       }
+      if (cls.onlyForRti) {
+        features.add(Tags.onlyForRti);
+      }
+      if (cls.onlyForConstructor) {
+        features.add(Tags.onlyForConstructor);
+      }
     }
     ClassUse classUse = checksBuilder.classUseMapForTesting[element];
     if (classUse != null) {
diff --git a/pkg/dart_internal/CHANGELOG.md b/pkg/dart_internal/CHANGELOG.md
new file mode 100644
index 0000000..d84bdda
--- /dev/null
+++ b/pkg/dart_internal/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.1.10
+
+- Support the latest Dart SDK.
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index 7b922fd..d499299 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,7 +1,6 @@
 name: dart_internal
 version: 0.1.10
-author: "Dart Team <misc@dartlang.org>"
-homepage: http://www.dartlang.org
+repository: https://github.com/dart-lang/sdk/tree/master/pkg/dart_internal
 description: >
   This package is not intended for wide use. It provides a temporary API to
   solve the problem: "Given an object some generic type A, how do I construct an
@@ -13,7 +12,8 @@
   into 2.0, so this package is provided as a temporary workaround.
 
   We will very likely remove support for this in a later version of Dart.
+
 environment:
   # Restrict the upper bound so that we can remove support for this in a later
   # version of the SDK without it being a breaking change.
-  sdk: ">=2.0.0-dev.12.0 <2.10.0"
+  sdk: ">=2.0.0 <2.10.0"
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 0b4e5f9..3056ea5 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -94,6 +94,16 @@
       args = List.from(args)..remove('--launch-dds');
     }
 
+    // These flags have a format that can't be handled by package:args, so
+    // while they are valid flags we'll assume the VM has verified them by this
+    // point.
+    args = args
+        .where(
+          (element) => !(element.contains('--observe') ||
+              element.contains('--enable-vm-service')),
+        )
+        .toList();
+
     // Before calling to run, send the first ping to analytics to have the first
     // ping, as well as the command itself, running in parallel.
     if (analytics.enabled) {
@@ -194,7 +204,7 @@
     addCommand(FormatCommand());
     addCommand(MigrateCommand(verbose: verbose));
     addCommand(PubCommand());
-    addCommand(RunCommand());
+    addCommand(RunCommand(verbose: verbose));
     addCommand(TestCommand());
   }
 
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index d118dbc..218d905 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -18,46 +18,133 @@
 
 class RunCommand extends DartdevCommand<int> {
   static bool launchDds = false;
+
+  // kErrorExitCode, as defined in runtime/bin/error_exit.h
+  static const errorExitCode = 255;
+
+  // This argument parser is here solely to ensure that VM specific flags are
+  // provided before any command and to provide a more consistent help message
+  // with the rest of the tool.
   @override
-  final ArgParser argParser = ArgParser.allowAnything();
+  final ArgParser argParser = ArgParser();
 
   @override
   final bool verbose;
 
-  RunCommand({this.verbose = false}) : super('run', '''
-Run a Dart file.''');
+  RunCommand({this.verbose = false})
+      : super(
+          'run',
+          'Run a Dart program.',
+        ) {
+    // NOTE: When updating this list of flags, be sure to add any VM flags to
+    // the list of flags in Options::ProcessVMDebuggingOptions in
+    // runtime/bin/main_options.cc. Failure to do so will result in those VM
+    // options being ignored.
+    argParser
+      ..addSeparator(
+        'Debugging options:',
+      )
+      ..addOption(
+        'observe',
+        help: 'The observe flag is a convenience flag used to run a program '
+            'with a set of common options useful for debugging.',
+        valueHelp: '[<port>[/<bind-address>]]',
+      )
+      ..addSeparator(
+        'Options implied by --observe are currently:',
+      )
+      ..addOption(
+        'enable-vm-service',
+        help: 'Enables the VM service and listens on the specified port for '
+            'connections (default port number is 8181, default bind address '
+            'is localhost).',
+        valueHelp: '[<port>[/<bind-address>]]',
+      )
+      ..addFlag(
+        'pause-isolates-on-exit',
+        help: 'Pause isolates on exit when '
+            'running with --enable-vm-service.',
+      )
+      ..addFlag(
+        'pause-isolates-on-unhandled-exceptions',
+        help: 'Pause isolates when an unhandled exception is encountered '
+            'when running with --enable-vm-service.',
+      )
+      ..addFlag(
+        'warn-on-pause-with-no-debugger',
+        help: 'Print a warning when an isolate pauses with no attached debugger'
+            ' when running with --enable-vm-service.',
+      )
+      ..addSeparator(
+        'Other debugging options include:',
+      )
+      ..addFlag(
+        'pause-isolates-on-start',
+        help: 'Pause isolates on start when '
+            'running with --enable-vm-service.',
+      )
+      ..addFlag(
+        'enable-asserts',
+        help: 'Enable assert statements.',
+      );
+
+    if (verbose) {
+      argParser
+        ..addSeparator(
+          'Advanced options:',
+        );
+    }
+    argParser
+      ..addFlag(
+        'disable-service-auth-codes',
+        hide: !verbose,
+        negatable: false,
+        help: 'Disables the requirement for an authentication code to '
+            'communicate with the VM service. Authentication codes help '
+            'protect against CSRF attacks, so it is not recommended to '
+            'disable them unless behind a firewall on a secure device.',
+      )
+      ..addFlag(
+        'enable-service-port-fallback',
+        hide: !verbose,
+        negatable: false,
+        help: 'When the VM service is told to bind to a particular port, '
+            'fallback to 0 if it fails to bind instread of failing to '
+            'start.',
+      )
+      ..addOption(
+        'namespace',
+        hide: !verbose,
+        valueHelp: 'path',
+        help: 'The path to a directory that dart:io calls will treat as the '
+            'root of the filesystem.',
+      )
+      ..addOption(
+        'root-certs-file',
+        hide: !verbose,
+        valueHelp: 'path',
+        help: 'The path to a file containing the trusted root certificates '
+            'to use for secure socket connections.',
+      )
+      ..addOption(
+        'root-certs-cache',
+        hide: !verbose,
+        valueHelp: 'path',
+        help: 'The path to a cache directory containing the trusted root '
+            'certificates to use for secure socket connections.',
+      )
+      ..addFlag(
+        'trace-loading',
+        hide: !verbose,
+        negatable: false,
+        help: 'Enables tracing of library and script loading.',
+      );
+  }
 
   @override
   String get invocation => '${super.invocation} <dart file | package target>';
 
   @override
-  void printUsage() {
-    // Override [printUsage] for invocations of 'dart help run' which won't
-    // execute [run] below.  Without this, the 'dart help run' reports the
-    // command pub with no commands or flags.
-    final command = sdk.dart;
-    final args = [
-      '--disable-dart-dev',
-      '--help',
-      if (verbose) '--verbose',
-    ];
-
-    log.trace('$command ${args.first}');
-
-    // Call 'dart --help'
-    // Process.runSync(..) is used since [printUsage] is not an async method,
-    // and we want to guarantee that the result (the help text for the console)
-    // is printed before command exits.
-    final result = Process.runSync(command, args);
-    if (result.stderr.isNotEmpty) {
-      stderr.write(result.stderr);
-    }
-    if (result.stdout.isNotEmpty) {
-      stdout.write(result.stdout);
-    }
-  }
-
-  @override
   FutureOr<int> run() async {
     // The command line arguments after 'run'
     var args = argResults.arguments.toList();
@@ -100,8 +187,7 @@
           'Could not find the implicit file to run: '
           'bin$separator$cwdName.dart.',
         );
-        // Error exit code, as defined in runtime/bin/error_exit.h
-        return 255;
+        return errorExitCode;
       }
     }
 
@@ -127,11 +213,15 @@
     if (launchDds) {
       debugSession = _DebuggingSession();
       if (!await debugSession.start()) {
-        return 255;
+        return errorExitCode;
       }
     }
+
     final path = args.firstWhere((e) => !e.startsWith('-'));
-    final runArgs = args.length == 1 ? <String>[] : args.sublist(1);
+    final pathIndex = args.indexOf(path);
+    final runArgs = (pathIndex + 1 == args.length)
+        ? <String>[]
+        : args.sublist(pathIndex + 1);
     VmInteropHandler.run(path, runArgs);
     return 0;
   }
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index ac2527a..1d71286 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -21,9 +21,9 @@
     p = project();
     var result = p.runSync('run', ['--help']);
 
-    expect(result.stdout, isEmpty);
-    expect(result.stderr, contains('Executes the Dart script'));
-    expect(result.stderr, contains('Common VM flags:'));
+    expect(result.stdout, contains('Run a Dart program.'));
+    expect(result.stdout, contains('Debugging options:'));
+    expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
   });
 
@@ -82,4 +82,100 @@
         contains('Could not find the implicit file to run: bin'));
     expect(result.exitCode, 255);
   });
+
+  test('arguments are properly passed', () {
+    p = project();
+    p.file('main.dart', 'void main(args) { print(args); }');
+    ProcessResult result = p.runSync('run', [
+      '--enable-experiment=non-nullable',
+      'main.dart',
+      'argument1',
+      'argument2'
+    ]);
+
+    // --enable-experiment and main.dart should not be passed.
+    expect(result.stdout, equals('[argument1, argument2]\n'));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
+  test('with accepted VM flags', () async {
+    p = project(mainSrc: "void main() { print('Hello World'); }");
+
+    // --observe sets the following flags by default:
+    //   --enable-vm-service
+    //   --pause-isolate-on-exit
+    //   --pause-isolate-on-unhandled-exception
+    //   --warn-on-pause-with-no-debugger
+    //
+    // This test ensures that allowed arguments for dart run which are valid VM
+    // arguments are properly handled by the VM.
+    ProcessResult result = p.runSync('run', [
+      '--observe',
+      '--pause-isolates-on-start',
+      // This should negate the above flag.
+      '--no-pause-isolates-on-start',
+      '--no-pause-isolates-on-exit',
+      '--no-pause-isolates-on-unhandled-exceptions',
+      p.relativeFilePath,
+    ]);
+
+    expect(
+      result.stdout,
+      contains('Observatory listening on'),
+    );
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
+  test('fails when provided verbose VM flags', () async {
+    p = project(mainSrc: "void main() { print('Hello World'); }");
+
+    // Any VM flags not listed under 'dart run help --verbose' should be passed
+    // before a dartdev command.
+    ProcessResult result = p.runSync('run', [
+      '--vm-name=foo',
+      p.relativeFilePath,
+    ]);
+
+    expect(result.stdout, isEmpty);
+    expect(
+      result.stderr,
+      contains('Could not find an option named "vm-name".'),
+    );
+    expect(result.exitCode, 64);
+  });
+
+  test('fails when provided unlisted VM flags', () async {
+    p = project(mainSrc: "void main() { print('Hello World'); }");
+
+    // Any VM flags not listed under 'dart run help --verbose' should be passed
+    // before a dartdev command.
+    ProcessResult result = p.runSync('run', [
+      '--verbose_gc',
+      p.relativeFilePath,
+    ]);
+
+    expect(result.stdout, isEmpty);
+    expect(
+      result.stderr,
+      contains('Could not find an option named "verbose_gc".'),
+    );
+    expect(result.exitCode, 64);
+  });
+
+  test('--enable-asserts', () async {
+    p = project(mainSrc: 'void main() { assert(false); }');
+
+    // Ensure --enable-asserts doesn't cause the dartdev isolate to fail to
+    // load. Regression test for: https://github.com/dart-lang/sdk/issues/42831
+    ProcessResult result = p.runSync('run', [
+      '--enable-asserts',
+      p.relativeFilePath,
+    ]);
+
+    expect(result.stdout, isEmpty);
+    expect(result.stderr, contains('Unhandled exception'));
+    expect(result.exitCode, 255);
+  });
 }
diff --git a/pkg/dds/dds_protocol.md b/pkg/dds/dds_protocol.md
index 8ac77ee..be9da7e 100644
--- a/pkg/dds/dds_protocol.md
+++ b/pkg/dds/dds_protocol.md
@@ -1,6 +1,6 @@
-# Dart Development Service Protocol 1.0
+# Dart Development Service Protocol 1.1
 
-This document describes _version 1.0_ of the Dart Development Service Protocol.
+This document describes _version 1.1_ of the Dart Development Service Protocol.
 This protocol is an extension of the Dart VM Service Protocol and implements it
 in it's entirety. For details on the VM Service Protocol, see the [Dart VM Service Protocol Specification][service-protocol].
 
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 2fbe99e..90b58e9 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -16,6 +16,8 @@
 
 import 'package:args/args.dart' show ArgParser;
 import 'package:path/path.dart' as p;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    as module_builder;
 
 enum NullSafety { strict, weak, disabled }
 
@@ -122,8 +124,8 @@
   var out = (options['out'] as String) ?? p.setExtension(entry, '.js');
   var libRoot = p.dirname(entry);
   var basename = p.basenameWithoutExtension(entry);
-  var libname = p.relative(p.withoutExtension(entry)).replaceAll('/', '__');
-  libname = libname.replaceAll('-', '_');
+  var libname =
+      module_builder.pathToJSIdentifier(p.relative(p.withoutExtension(entry)));
 
   // By default (no `-d`), we use the `dartdevc` binary on the user's path to
   // compute the SDK we use for execution.  I.e., we assume that `dart` is
@@ -280,7 +282,7 @@
       sdk.dart.nonNullAsserts($nonNullAsserts);
     }
     sdk._debugger.registerDevtoolsFormatter();
-    app.$libname.main();
+    app.$libname.main([]);
   });
 </script>
 ''';
@@ -347,7 +349,7 @@
     dart.nonNullAsserts($nonNullAsserts);
   }
   _isolate_helper.startRootIsolate(() => {}, []);
-  main();
+  main([]);
 } catch(e) {
   console.error(e);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 8ed64425..bf4ca5e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -433,14 +433,12 @@
     inferrer.inferConstructorParameterTypes(node.target);
     bool hasExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    InvocationInferenceResult result = inferrer.inferInvocation(
-        typeContext,
-        node.fileOffset,
+    FunctionType functionType = replaceReturnType(
         node.target.function
             .computeThisFunctionType(inferrer.library.nonNullable),
-        node.arguments,
-        returnType:
-            computeConstructorReturnType(node.target, inferrer.coreTypes),
+        computeConstructorReturnType(node.target, inferrer.coreTypes));
+    InvocationInferenceResult result = inferrer.inferInvocation(
+        typeContext, node.fileOffset, functionType, node.arguments,
         isConst: node.isConst);
     if (!inferrer.isTopLevel) {
       SourceLibraryBuilder library = inferrer.library;
@@ -721,14 +719,14 @@
       FactoryConstructorInvocationJudgment node, DartType typeContext) {
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    InvocationInferenceResult result = inferrer.inferInvocation(
-        typeContext,
-        node.fileOffset,
+
+    FunctionType functionType = replaceReturnType(
         node.target.function
             .computeThisFunctionType(inferrer.library.nonNullable),
-        node.arguments,
-        returnType:
-            computeConstructorReturnType(node.target, inferrer.coreTypes),
+        computeConstructorReturnType(node.target, inferrer.coreTypes));
+
+    InvocationInferenceResult result = inferrer.inferInvocation(
+        typeContext, node.fileOffset, functionType, node.arguments,
         isConst: node.isConst);
     node.hasBeenInferred = true;
     Expression resultNode = node;
@@ -757,9 +755,10 @@
     FunctionType calleeType = node.target.function
         .computeAliasedConstructorFunctionType(
             typedef, inferrer.library.library);
+    calleeType = replaceReturnType(calleeType, calleeType.returnType.unalias);
     InvocationInferenceResult result = inferrer.inferInvocation(
         typeContext, node.fileOffset, calleeType, node.arguments,
-        returnType: calleeType.returnType.unalias, isConst: node.isConst);
+        isConst: node.isConst);
     node.hasBeenInferred = true;
     Expression resultNode = node;
     if (!inferrer.isTopLevel) {
@@ -784,9 +783,10 @@
     Typedef typedef = node.typeAliasBuilder.typedef;
     FunctionType calleeType = node.target.function
         .computeAliasedFactoryFunctionType(typedef, inferrer.library.library);
+    calleeType = replaceReturnType(calleeType, calleeType.returnType.unalias);
     InvocationInferenceResult result = inferrer.inferInvocation(
         typeContext, node.fileOffset, calleeType, node.arguments,
-        returnType: calleeType.returnType.unalias, isConst: node.isConst);
+        isConst: node.isConst);
     node.hasBeenInferred = true;
     Expression resultNode = node;
     if (!inferrer.isTopLevel) {
@@ -1133,14 +1133,13 @@
     Substitution substitution = Substitution.fromSupertype(
         inferrer.classHierarchy.getClassAsInstanceOf(
             inferrer.thisType.classNode, node.target.enclosingClass));
-    inferrer.inferInvocation(
-        null,
-        node.fileOffset,
+    FunctionType functionType = replaceReturnType(
         substitution.substituteType(node.target.function
             .computeThisFunctionType(inferrer.library.nonNullable)
             .withoutTypeParameters),
-        node.argumentsJudgment,
-        returnType: inferrer.thisType,
+        inferrer.thisType);
+    inferrer.inferInvocation(
+        null, node.fileOffset, functionType, node.argumentsJudgment,
         skipTypeArgumentInference: true);
   }
 
@@ -5013,14 +5012,13 @@
           classTypeParameters[i], inferrer.library.library);
     }
     ArgumentsImpl.setNonInferrableArgumentTypes(node.arguments, typeArguments);
-    inferrer.inferInvocation(
-        null,
-        node.fileOffset,
+    FunctionType functionType = replaceReturnType(
         node.target.function
             .computeThisFunctionType(inferrer.library.nonNullable),
-        node.arguments,
-        returnType: inferrer.coreTypes.thisInterfaceType(
-            node.target.enclosingClass, inferrer.library.nonNullable),
+        inferrer.coreTypes.thisInterfaceType(
+            node.target.enclosingClass, inferrer.library.nonNullable));
+    inferrer.inferInvocation(
+        null, node.fileOffset, functionType, node.arguments,
         skipTypeArgumentInference: true);
     ArgumentsImpl.removeNonInferrableArgumentTypes(node.arguments);
   }
@@ -5225,14 +5223,13 @@
     Substitution substitution = Substitution.fromSupertype(
         inferrer.classHierarchy.getClassAsInstanceOf(
             inferrer.thisType.classNode, node.target.enclosingClass));
-    inferrer.inferInvocation(
-        null,
-        node.fileOffset,
+    FunctionType functionType = replaceReturnType(
         substitution.substituteType(node.target.function
             .computeThisFunctionType(inferrer.library.nonNullable)
             .withoutTypeParameters),
-        node.arguments,
-        returnType: inferrer.thisType,
+        inferrer.thisType);
+    inferrer.inferInvocation(
+        null, node.fileOffset, functionType, node.arguments,
         skipTypeArgumentInference: true);
   }
 
@@ -5511,12 +5508,17 @@
       isDefinitelyAssigned = inferrer.flowAnalysis.isAssigned(variable);
     }
     DartType declaredOrInferredType = variable.lateType ?? variable.type;
-    DartType writeContext = declaredOrInferredType;
-    ExpressionInferenceResult rhsResult = inferrer.inferExpression(
-        node.value, writeContext ?? const UnknownType(), true,
+    DartType promotedType;
+    if (inferrer.isNonNullableByDefault) {
+      promotedType = inferrer.flowAnalysis.promotedType(variable);
+    }
+    ExpressionInferenceResult rhsResult = inferrer.inferExpression(node.value,
+        promotedType ?? declaredOrInferredType ?? const UnknownType(), true,
         isVoidAllowed: true);
-    Expression rhs = inferrer.ensureAssignableResult(writeContext, rhsResult,
-        fileOffset: node.fileOffset, isVoidAllowed: writeContext is VoidType);
+    Expression rhs = inferrer.ensureAssignableResult(
+        declaredOrInferredType, rhsResult,
+        fileOffset: node.fileOffset,
+        isVoidAllowed: declaredOrInferredType is VoidType);
     inferrer.flowAnalysis.write(variable, rhsResult.inferredType);
     DartType resultType = rhsResult.inferredType;
     Expression resultExpression;
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 4586a2a..0603833 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
@@ -218,14 +218,6 @@
   /// inside a closure.
   ClosureContext closureContext;
 
-  /// The [Substitution] inferred by the last [inferInvocation], or `null` if
-  /// the last invocation didn't require any inference.
-  Substitution lastInferredSubstitution;
-
-  /// The [FunctionType] of the callee in the last [inferInvocation], or `null`
-  /// if the last invocation didn't require any inference.
-  FunctionType lastCalleeType;
-
   TypeInferrerImpl(this.engine, this.uriForInstrumentation, bool topLevel,
       this.thisType, this.library, this.assignedVariables, this.dataForTesting)
       : assert(library != null),
@@ -1653,20 +1645,13 @@
       {List<VariableDeclaration> hoistedExpressions,
       bool isSpecialCasedBinaryOperator: false,
       bool isSpecialCasedTernaryOperator: false,
-      DartType returnType,
       DartType receiverType,
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false,
       bool isImplicitCall: false}) {
-    assert(
-        returnType == null || !containsFreeFunctionTypeVariables(returnType),
-        "Return type $returnType contains free variables."
-        "Provided function type: $calleeType.");
     int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
     if (extensionTypeParameterCount != 0) {
-      assert(returnType == null,
-          "Unexpected explicit return type for extension method invocation.");
       return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
           typeContext, offset, calleeType, arguments, hoistedExpressions,
           isSpecialCasedBinaryOperator: isSpecialCasedBinaryOperator,
@@ -1681,7 +1666,6 @@
         isSpecialCasedBinaryOperator: isSpecialCasedBinaryOperator,
         isSpecialCasedTernaryOperator: isSpecialCasedTernaryOperator,
         receiverType: receiverType,
-        returnType: returnType,
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst,
         isImplicitExtensionMember: isImplicitExtensionMember,
@@ -1770,17 +1754,10 @@
       {bool isSpecialCasedBinaryOperator: false,
       bool isSpecialCasedTernaryOperator: false,
       DartType receiverType,
-      DartType returnType,
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false,
       bool isImplicitCall}) {
-    assert(
-        returnType == null || !containsFreeFunctionTypeVariables(returnType),
-        "Return type $returnType contains free variables."
-        "Provided function type: $calleeType.");
-    lastInferredSubstitution = null;
-    lastCalleeType = null;
     List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
     if (calleeTypeParameters.isNotEmpty) {
       // It's possible that one of the callee type parameters might match a type
@@ -1794,9 +1771,6 @@
       // in which me must do this, to avoid a performance regression?
       FreshTypeParameters fresh = getFreshTypeParameters(calleeTypeParameters);
       calleeType = fresh.applyToFunctionType(calleeType);
-      if (returnType != null) {
-        returnType = fresh.substitute(returnType);
-      }
       calleeTypeParameters = fresh.freshTypeParameters;
     }
     List<DartType> explicitTypeArguments = getExplicitTypeArguments(arguments);
@@ -1825,8 +1799,8 @@
           calleeTypeParameters.length, const UnknownType());
       typeSchemaEnvironment.inferGenericFunctionOrType(
           isNonNullableByDefault
-              ? returnType ?? calleeType.returnType
-              : legacyErasure(coreTypes, returnType ?? calleeType.returnType),
+              ? calleeType.returnType
+              : legacyErasure(coreTypes, calleeType.returnType),
           calleeTypeParameters,
           null,
           null,
@@ -1893,12 +1867,16 @@
       }
     }
     if (isSpecialCasedBinaryOperator) {
-      returnType = typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator(
-          receiverType, actualTypes[0],
-          isNonNullableByDefault: isNonNullableByDefault);
+      calleeType = replaceReturnType(
+          calleeType,
+          typeSchemaEnvironment.getTypeOfSpecialCasedBinaryOperator(
+              receiverType, actualTypes[0],
+              isNonNullableByDefault: isNonNullableByDefault));
     } else if (isSpecialCasedTernaryOperator) {
-      returnType = typeSchemaEnvironment.getTypeOfSpecialCasedTernaryOperator(
-          receiverType, actualTypes[0], actualTypes[1], library.library);
+      calleeType = replaceReturnType(
+          calleeType,
+          typeSchemaEnvironment.getTypeOfSpecialCasedTernaryOperator(
+              receiverType, actualTypes[0], actualTypes[1], library.library));
     }
     for (NamedExpression namedArgument in arguments.named) {
       DartType formalType =
@@ -1968,7 +1946,7 @@
 
     if (inferenceNeeded) {
       typeSchemaEnvironment.inferGenericFunctionOrType(
-          returnType ?? calleeType.returnType,
+          calleeType.returnType,
           calleeTypeParameters,
           formalTypes,
           actualTypes,
@@ -2034,19 +2012,11 @@
       }
     }
     DartType inferredType;
-    lastInferredSubstitution = substitution;
-    lastCalleeType = calleeType;
-    if (returnType != null) {
-      inferredType = substitution == null
-          ? returnType
-          : substitution.substituteType(returnType);
-    } else {
-      if (substitution != null) {
-        calleeType =
-            substitution.substituteType(calleeType.withoutTypeParameters);
-      }
-      inferredType = calleeType.returnType;
+    if (substitution != null) {
+      calleeType =
+          substitution.substituteType(calleeType.withoutTypeParameters);
     }
+    inferredType = calleeType.returnType;
     assert(
         !containsFreeFunctionTypeVariables(inferredType),
         "Inferred return type $inferredType contains free variables."
@@ -2112,7 +2082,8 @@
     Substitution substitution;
     List<DartType> formalTypesFromContext =
         new List<DartType>.filled(formals.length, null);
-    if (typeContext is FunctionType) {
+    if (typeContext is FunctionType &&
+        typeContext.typeParameters.length == typeParameters.length) {
       for (int i = 0; i < formals.length; i++) {
         if (i < function.positionalParameters.length) {
           formalTypesFromContext[i] =
@@ -4226,3 +4197,11 @@
 
   TypedTearoff(this.tearoffType, this.tearoff);
 }
+
+FunctionType replaceReturnType(FunctionType functionType, DartType returnType) {
+  return new FunctionType(functionType.positionalParameters, returnType,
+      functionType.declaredNullability,
+      requiredParameterCount: functionType.requiredParameterCount,
+      namedParameters: functionType.namedParameters,
+      typeParameters: functionType.typeParameters);
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index e146a54..1b89f55 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -2,20 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-import 'package:kernel/ast.dart'
-    show
-        DartType,
-        DynamicType,
-        FunctionType,
-        FutureOrType,
-        InterfaceType,
-        Library,
-        NamedType,
-        NeverType,
-        Nullability,
-        Procedure,
-        TypeParameter,
-        Variance;
+import 'package:kernel/ast.dart' hide MapEntry;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
@@ -370,46 +357,6 @@
             preferUpwardsInference: !typeParam.isLegacyCovariant);
       }
     }
-
-    // If the downwards infer phase has failed, we'll catch this in the upwards
-    // phase later on.
-    if (downwardsInferPhase) {
-      return;
-    }
-
-    // Check the inferred types against all of the constraints.
-    Map<TypeParameter, DartType> knownTypes = <TypeParameter, DartType>{};
-    for (int i = 0; i < typeParametersToInfer.length; i++) {
-      TypeParameter typeParam = typeParametersToInfer[i];
-      TypeConstraint constraint = constraints[typeParam];
-      DartType typeParamBound =
-          Substitution.fromPairs(typeParametersToInfer, inferredTypes)
-              .substituteType(typeParam.bound);
-
-      DartType inferred = inferredTypes[i];
-      bool success = typeSatisfiesConstraint(inferred, constraint);
-      if (success && !hasOmittedBound(typeParam)) {
-        // If everything else succeeded, check the `extends` constraint.
-        DartType extendsConstraint = typeParamBound;
-        success = isSubtypeOf(
-            inferred, extendsConstraint, SubtypeCheckMode.withNullabilities);
-      }
-
-      if (!success) {
-        // TODO(paulberry): report error.
-
-        // Heuristic: even if we failed, keep the erroneous type.
-        // It should satisfy at least some of the constraints (e.g. the return
-        // context). If we fall back to instantiateToBounds, we'll typically get
-        // more errors (e.g. because `dynamic` is the most common bound).
-      }
-
-      if (isKnown(inferred)) {
-        knownTypes[typeParam] = inferred;
-      }
-    }
-
-    // TODO(paulberry): report any errors from instantiateToBounds.
   }
 
   @override
@@ -480,7 +427,8 @@
   /// If [isContravariant] is `true`, then we are solving for a contravariant
   /// type parameter which means we choose the upper bound rather than the
   /// lower bound for normally covariant type parameters.
-  DartType solveTypeConstraint(TypeConstraint constraint, DartType bottomType,
+  DartType solveTypeConstraint(
+      TypeConstraint constraint, DartType topType, DartType bottomType,
       {bool grounded: false, bool isContravariant: false}) {
     assert(bottomType == const NeverType(Nullability.nonNullable) ||
         bottomType == coreTypes.nullType);
@@ -493,12 +441,14 @@
       // e.g. `Iterable<?>`
       if (constraint.lower is! UnknownType) {
         return grounded
-            ? leastClosure(constraint.lower, const DynamicType(), bottomType)
+            ? leastClosure(constraint.lower, topType, bottomType)
             : constraint.lower;
-      } else {
+      } else if (constraint.upper is! UnknownType) {
         return grounded
-            ? greatestClosure(constraint.upper, const DynamicType(), bottomType)
+            ? greatestClosure(constraint.upper, topType, bottomType)
             : constraint.upper;
+      } else {
+        return grounded ? const DynamicType() : const UnknownType();
       }
     } else {
       // Prefer the known bound, if any.
@@ -509,12 +459,14 @@
       // e.g. `Iterable<?>`
       if (constraint.upper is! UnknownType) {
         return grounded
-            ? greatestClosure(constraint.upper, const DynamicType(), bottomType)
+            ? greatestClosure(constraint.upper, topType, bottomType)
             : constraint.upper;
-      } else {
+      } else if (constraint.lower is! UnknownType) {
         return grounded
-            ? leastClosure(constraint.lower, const DynamicType(), bottomType)
+            ? leastClosure(constraint.lower, topType, bottomType)
             : constraint.lower;
+      } else {
+        return grounded ? bottomType : const UnknownType();
       }
     }
   }
@@ -548,6 +500,9 @@
     return solveTypeConstraint(
         constraint,
         clientLibrary.isNonNullableByDefault
+            ? coreTypes.objectNullableRawType
+            : const DynamicType(),
+        clientLibrary.isNonNullableByDefault
             ? const NeverType(Nullability.nonNullable)
             : nullType,
         grounded: true,
@@ -559,6 +514,9 @@
     DartType t = solveTypeConstraint(
         constraint,
         clientLibrary.isNonNullableByDefault
+            ? coreTypes.objectNullableRawType
+            : const DynamicType(),
+        clientLibrary.isNonNullableByDefault
             ? const NeverType(Nullability.nonNullable)
             : nullType);
     if (!isKnown(t)) {
@@ -578,6 +536,9 @@
       return solveTypeConstraint(
           constraint,
           clientLibrary.isNonNullableByDefault
+              ? coreTypes.objectNullableRawType
+              : const DynamicType(),
+          clientLibrary.isNonNullableByDefault
               ? const NeverType(Nullability.nonNullable)
               : nullType);
     }
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index e8b5454..6459cc1 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -439,6 +439,8 @@
 InvalidVoid/part_wrapped_script2: Fail
 InvalidVoid/script1: Fail
 InvalidVoid/script2: Fail
+JsInteropAnonymousFactoryPositionalParameters/analyzerCode: Fail # Web compiler specific
+JsInteropAnonymousFactoryPositionalParameters/example: Fail # Web compiler specific
 JsInteropIndexNotSupported/analyzerCode: Fail # Web compiler specific
 JsInteropIndexNotSupported/example: Fail # Web compiler specific
 JsInteropNamedParameters/analyzerCode: Fail # Web compiler specific
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index ecf30d2..62ae4a3 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -4086,6 +4086,10 @@
 NullableMixinError:
   template: "Can't mix '#name' in because it's marked with '?'."
 
+JsInteropAnonymousFactoryPositionalParameters:
+  template: "Factory constructors for @anonymous JS interop classes should not contain any positional parameters."
+  tip: "Try replacing them with named parameters instead."
+
 JsInteropIndexNotSupported:
   template: "JS interop classes do not support [] and []= operator methods."
   tip: "Try replacing with a normal method."
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
index 8d661f0..425e5c2 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -56,6 +56,7 @@
 String expectedCrashLine;
 bool byteDelete = false;
 bool askAboutRedirectCrashTarget = false;
+int stackTraceMatches = 1;
 Set<String> askedAboutRedirect = {};
 
 main(List<String> arguments) async {
@@ -85,6 +86,9 @@
         byteDelete = true;
       } else if (arg == "--ask-redirect-target") {
         askAboutRedirectCrashTarget = true;
+      } else if (arg.startsWith("--stack-matches=")) {
+        String stackMatches = arg.substring("--stack-matches=".length);
+        stackTraceMatches = int.parse(stackMatches);
       } else {
         throw "Unknown option $arg";
       }
@@ -487,16 +491,22 @@
     // Find line with #0 in it.
     String eWithSt = "$e\n\n$st";
     List<String> lines = eWithSt.split("\n");
-    String foundLine;
+    String foundLine = "";
+    int lookFor = 0;
     for (String line in lines) {
-      if (line.startsWith("#0")) {
-        foundLine = line;
-        break;
+      if (line.startsWith("#$lookFor")) {
+        foundLine += line;
+        lookFor++;
+        if (lookFor >= stackTraceMatches) {
+          break;
+        } else {
+          foundLine += "\n";
+        }
       }
     }
     if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
     if (expectedCrashLine == null) {
-      print("Got $foundLine");
+      print("Got '$foundLine'");
       expectedCrashLine = foundLine;
       return true;
     } else if (foundLine == expectedCrashLine) {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
index 168cf74..0d4d9c9 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
@@ -41,6 +41,8 @@
 
   DartType get bottomType => const NeverType(Nullability.nonNullable);
 
+  DartType get topType => coreTypes.objectNullableRawType;
+
   /// Converts the [text] representation of a type into a type.
   ///
   /// If [environment] is passed it's used to resolve the type terms in [text].
@@ -734,7 +736,8 @@
 
     // Upwards inference should refine that to List<List<dynamic>*>*
     env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib);
-    expect(inferredTypes[0], _list(new DynamicType()));
+    expect(inferredTypes[0],
+        _list(new InterfaceType(objectClass, Nullability.nullable)));
   }
 
   void test_upper_bound_classic() {
@@ -1095,71 +1098,73 @@
     // TODO(dmitryas): Test for various nullabilities.
 
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint(), bottomType),
+    expect(env.solveTypeConstraint(_makeConstraint(), topType, bottomType),
         new UnknownType());
 
     // Solve(? <: T <: ?, grounded) => dynamic
     expect(
-        env.solveTypeConstraint(_makeConstraint(), bottomType, grounded: true),
+        env.solveTypeConstraint(_makeConstraint(), topType, bottomType,
+            grounded: true),
         new DynamicType());
 
     // Solve(A <: T <: ?) => A
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<dynamic>*")), bottomType),
+            _makeConstraint(lower: toType("A<dynamic>*")), topType, bottomType),
         toType("A<dynamic>*"));
 
     // Solve(A <: T <: ?, grounded) => A
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<dynamic>*")), bottomType,
+            _makeConstraint(lower: toType("A<dynamic>*")), topType, bottomType,
             grounded: true),
         toType("A<dynamic>*"));
 
     // Solve(A<?>* <: T <: ?) => A<?>*
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<unknown>*")), bottomType),
+            _makeConstraint(lower: toType("A<unknown>*")), topType, bottomType),
         toType("A<unknown>*"));
 
     // Solve(A<?>* <: T <: ?, grounded) => A<Never>*
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(lower: toType("A<unknown>*")), bottomType,
+            _makeConstraint(lower: toType("A<unknown>*")), topType, bottomType,
             grounded: true),
         toType("A<Never>*"));
 
     // Solve(? <: T <: A*) => A*
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<dynamic>*")), bottomType),
+            _makeConstraint(upper: toType("A<dynamic>*")), topType, bottomType),
         toType("A<dynamic>*"));
 
     // Solve(? <: T <: A*, grounded) => A*
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<dynamic>*")), bottomType,
+            _makeConstraint(upper: toType("A<dynamic>*")), topType, bottomType,
             grounded: true),
         toType("A<dynamic>*"));
 
     // Solve(? <: T <: A<?>*) => A<?>*
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<unknown>*")), bottomType),
+            _makeConstraint(upper: toType("A<unknown>*")), topType, bottomType),
         toType("A<unknown>*"));
 
     // Solve(? <: T <: A<?>*, grounded) => A<dynamic>*
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(upper: toType("A<unknown>*")), bottomType,
+            _makeConstraint(upper: toType("A<unknown>*")), topType, bottomType,
             grounded: true),
-        toType("A<dynamic>*"));
+        toType("A<Object?>*"));
 
     // Solve(B* <: T <: A*) => B*
     expect(
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
+            topType,
             bottomType),
         toType("B<dynamic>*"));
 
@@ -1168,6 +1173,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
+            topType,
             bottomType,
             grounded: true),
         toType("B<dynamic>*"));
@@ -1177,6 +1183,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
+            topType,
             bottomType),
         toType("A<dynamic>*"));
 
@@ -1185,6 +1192,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
+            topType,
             bottomType,
             grounded: true),
         toType("A<dynamic>*"));
@@ -1194,6 +1202,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
+            topType,
             bottomType),
         toType("B<dynamic>*"));
 
@@ -1202,6 +1211,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
+            topType,
             bottomType,
             grounded: true),
         toType("B<dynamic>*"));
@@ -1211,6 +1221,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
+            topType,
             bottomType),
         toType("B<unknown>*"));
 
@@ -1219,6 +1230,7 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
+            topType,
             bottomType,
             grounded: true),
         toType("B<Never>*"));
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index c1c1468..aedad18 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -60,6 +60,8 @@
 
   DartType get bottomType => nullType;
 
+  DartType get topType => const DynamicType();
+
   void test_addLowerBound() {
     var A = coreTypes.legacyRawType(_addClass(_class('A')));
     var B = coreTypes.legacyRawType(
@@ -636,17 +638,20 @@
         Nullability.legacy);
     var env = _makeEnv();
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint(), bottomType),
+    expect(env.solveTypeConstraint(_makeConstraint(), topType, bottomType),
         same(unknownType));
     // Solve(? <: T <: ?, grounded) => dynamic
     expect(
-        env.solveTypeConstraint(_makeConstraint(), bottomType, grounded: true),
+        env.solveTypeConstraint(_makeConstraint(), topType, bottomType,
+            grounded: true),
         dynamicType);
     // Solve(A <: T <: ?) => A
-    expect(env.solveTypeConstraint(_makeConstraint(lower: A), bottomType), A);
+    expect(
+        env.solveTypeConstraint(_makeConstraint(lower: A), topType, bottomType),
+        A);
     // Solve(A <: T <: ?, grounded) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: A), bottomType,
+        env.solveTypeConstraint(_makeConstraint(lower: A), topType, bottomType,
             grounded: true),
         A);
     // Solve(A<?> <: T <: ?) => A<?>
@@ -655,6 +660,7 @@
             _makeConstraint(
                 lower: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType),
         new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
     // Solve(A<?> <: T <: ?, grounded) => A<Null>
@@ -663,14 +669,17 @@
             _makeConstraint(
                 lower: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType,
             grounded: true),
         new InterfaceType(A.classNode, Nullability.legacy, [nullType]));
     // Solve(? <: T <: A) => A
-    expect(env.solveTypeConstraint(_makeConstraint(upper: A), bottomType), A);
+    expect(
+        env.solveTypeConstraint(_makeConstraint(upper: A), topType, bottomType),
+        A);
     // Solve(? <: T <: A, grounded) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(upper: A), bottomType,
+        env.solveTypeConstraint(_makeConstraint(upper: A), topType, bottomType,
             grounded: true),
         A);
     // Solve(? <: T <: A<?>) => A<?>
@@ -679,6 +688,7 @@
             _makeConstraint(
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType),
         new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
     // Solve(? <: T <: A<?>, grounded) => A<dynamic>
@@ -687,17 +697,19 @@
             _makeConstraint(
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType,
             grounded: true),
         new InterfaceType(A.classNode, Nullability.legacy, [dynamicType]));
     // Solve(B <: T <: A) => B
     expect(
         env.solveTypeConstraint(
-            _makeConstraint(lower: B, upper: A), bottomType),
+            _makeConstraint(lower: B, upper: A), topType, bottomType),
         B);
     // Solve(B <: T <: A, grounded) => B
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: B, upper: A), bottomType,
+        env.solveTypeConstraint(
+            _makeConstraint(lower: B, upper: A), topType, bottomType,
             grounded: true),
         B);
     // Solve(B<?> <: T <: A) => A
@@ -707,6 +719,7 @@
                 lower: new InterfaceType(
                     B.classNode, Nullability.legacy, [unknownType]),
                 upper: A),
+            topType,
             bottomType),
         A);
     // Solve(B<?> <: T <: A, grounded) => A
@@ -716,6 +729,7 @@
                 lower: new InterfaceType(
                     B.classNode, Nullability.legacy, [unknownType]),
                 upper: A),
+            topType,
             bottomType,
             grounded: true),
         A);
@@ -726,6 +740,7 @@
                 lower: B,
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType),
         B);
     // Solve(B <: T <: A<?>, grounded) => B
@@ -735,6 +750,7 @@
                 lower: B,
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType,
             grounded: true),
         B);
@@ -746,6 +762,7 @@
                     B.classNode, Nullability.legacy, [unknownType]),
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType),
         new InterfaceType(B.classNode, Nullability.legacy, [unknownType]));
     // Solve(B<?> <: T <: A<?>) => B<Null>
@@ -756,6 +773,7 @@
                     B.classNode, Nullability.legacy, [unknownType]),
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            topType,
             bottomType,
             grounded: true),
         new InterfaceType(B.classNode, Nullability.legacy, [nullType]));
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index bf40c56..4a4024c 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -552,6 +552,8 @@
 tails
 talk
 templates
+test3a
+test3b
 thereof
 thing
 threw
diff --git a/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart
new file mode 100644
index 0000000..981a32f
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, 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.
+
+typedef F<T> = T Function(T, T);
+
+test1() {
+  F<int> d = (int a, int b) => a;
+  d = <S>(S a, S b) => a;
+}
+
+test2() {
+  F<int> d = (int a, int b) => a;
+  var f = <S>(S a, S b) => a;
+  d = f;
+}
+
+test3a() {
+  F<int> d = (int a, int b) => a;
+  d = <S>(a, S b) => a;
+}
+
+test3b() {
+  F<int> d = (int a, int b) => a;
+  d = <S>(a, S b) => b;
+}
+
+test4() {
+  F<int> d = (int a, int b) => a;
+  d = <S>(a, b) => a;
+}
+
+test5() {
+  F<int> d = (int a, int b) => a;
+  d = (a, b, c) => a;
+}
+
+test6() {
+  F<int> d = (int a, int b) => a;
+  d = (a) => a;
+}
+
+test7() {
+  F<int> d = (int a, int b) => a;
+  d = <S>(a, b, c) => a;
+}
+
+test8() {
+  F<int> d = (int a, int b) => a;
+  d = <S>(a) => a;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.outline.expect b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.outline.expect
new file mode 100644
index 0000000..cce5025
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.outline.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object* = dynamic> = (T*, T*) →* T*;
+static method test1() → dynamic
+  ;
+static method test2() → dynamic
+  ;
+static method test3a() → dynamic
+  ;
+static method test3b() → dynamic
+  ;
+static method test4() → dynamic
+  ;
+static method test5() → dynamic
+  ;
+static method test6() → dynamic
+  ;
+static method test7() → dynamic
+  ;
+static method test8() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.strong.expect b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.strong.expect
new file mode 100644
index 0000000..0ee5386
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.strong.expect
@@ -0,0 +1,100 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:9:10: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(S a, S b) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:15:7: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = f;
+//       ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:20:10: Error: A value of type 'dynamic Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, S b) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:25:10: Error: A value of type 'S Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, S b) => b;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:30:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, b) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:35:7: Error: A value of type 'int Function(int, int, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = (a, b, c) => a;
+//       ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:40:7: Error: A value of type 'int Function(int)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = (a) => a;
+//       ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:45:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, b, c) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:50:10: Error: A value of type 'dynamic Function<S>(dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a) => a;
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object* = dynamic> = (T*, T*) →* T*;
+static method test1() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:9:10: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(S a, S b) => a;
+         ^" in (<S extends core::Object* = dynamic>(S* a, S* b) → S* => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test2() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  <S extends core::Object* = dynamic>(S*, S*) →* S* f = <S extends core::Object* = dynamic>(S* a, S* b) → S* => a;
+  d = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:15:7: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = f;
+      ^" in f as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test3a() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:20:10: Error: A value of type 'dynamic Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, S b) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, S* b) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test3b() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:25:10: Error: A value of type 'S Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, S b) => b;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, S* b) → S* => b) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test4() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:30:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, b) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, dynamic b) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test5() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:35:7: Error: A value of type 'int Function(int, int, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = (a, b, c) => a;
+      ^" in ((core::int* a, core::int* b, dynamic c) → core::int* => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test6() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:40:7: Error: A value of type 'int Function(int)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = (a) => a;
+      ^" in ((core::int* a) → core::int* => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test7() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:45:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, b, c) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, dynamic b, dynamic c) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test8() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:50:10: Error: A value of type 'dynamic Function<S>(dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.strong.transformed.expect b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.strong.transformed.expect
new file mode 100644
index 0000000..0ee5386
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.strong.transformed.expect
@@ -0,0 +1,100 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:9:10: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(S a, S b) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:15:7: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = f;
+//       ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:20:10: Error: A value of type 'dynamic Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, S b) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:25:10: Error: A value of type 'S Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, S b) => b;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:30:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, b) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:35:7: Error: A value of type 'int Function(int, int, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = (a, b, c) => a;
+//       ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:40:7: Error: A value of type 'int Function(int)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = (a) => a;
+//       ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:45:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a, b, c) => a;
+//          ^
+//
+// pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:50:10: Error: A value of type 'dynamic Function<S>(dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+//   d = <S>(a) => a;
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object* = dynamic> = (T*, T*) →* T*;
+static method test1() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:9:10: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(S a, S b) => a;
+         ^" in (<S extends core::Object* = dynamic>(S* a, S* b) → S* => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test2() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  <S extends core::Object* = dynamic>(S*, S*) →* S* f = <S extends core::Object* = dynamic>(S* a, S* b) → S* => a;
+  d = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:15:7: Error: A value of type 'S Function<S>(S, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = f;
+      ^" in f as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test3a() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:20:10: Error: A value of type 'dynamic Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, S b) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, S* b) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test3b() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:25:10: Error: A value of type 'S Function<S>(dynamic, S)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, S b) => b;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, S* b) → S* => b) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test4() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:30:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, b) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, dynamic b) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test5() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:35:7: Error: A value of type 'int Function(int, int, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = (a, b, c) => a;
+      ^" in ((core::int* a, core::int* b, dynamic c) → core::int* => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test6() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:40:7: Error: A value of type 'int Function(int)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = (a) => a;
+      ^" in ((core::int* a) → core::int* => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test7() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:45:10: Error: A value of type 'dynamic Function<S>(dynamic, dynamic, dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a, b, c) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a, dynamic b, dynamic c) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method test8() → dynamic {
+  (core::int*, core::int*) →* core::int* d = (core::int* a, core::int* b) → core::int* => a;
+  d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart:50:10: Error: A value of type 'dynamic Function<S>(dynamic)' can't be assigned to a variable of type 'int Function(int, int)'.
+  d = <S>(a) => a;
+         ^" in (<S extends core::Object* = dynamic>(dynamic a) → dynamic => a) as{TypeError} (core::int*, core::int*) →* core::int*;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..7f419b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+typedef F<T> = T Function(T, T);
+test1() {}
+test2() {}
+test3a() {}
+test3b() {}
+test4() {}
+test5() {}
+test6() {}
+test7() {}
+test8() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a807d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_generic_type_parameter_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+main() {}
+test1() {}
+test2() {}
+test3a() {}
+test3b() {}
+test4() {}
+test5() {}
+test6() {}
+test7() {}
+test8() {}
+typedef F<T> = T Function(T, T);
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart
new file mode 100644
index 0000000..745b6b5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, 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.
+
+typedef F<T> = T Function(T, T);
+
+test1() {
+  dynamic d = (int a, int b) => a;
+  d as F<int>; // Promote [d] to `int Function(int, int)`.
+  d = <S>(S a, S b) => a;
+}
+
+test2() {
+  dynamic d = (int a, int b) => a;
+  d as F<int>; // Promote [d] to `int Function(int, int)`.
+  d = (a, b) => '$a';
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.outline.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.outline.expect
new file mode 100644
index 0000000..c2a211c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.outline.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object? = dynamic> = (T%, T%) → T%;
+static method test1() → dynamic
+  ;
+static method test2() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.strong.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.strong.expect
new file mode 100644
index 0000000..3de8d0f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.strong.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+//   d = (a, b) => '$a';
+//                     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object? = dynamic> = (T%, T%) → T%;
+static method test1() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = <S extends core::Object? = dynamic>(S% a, S% b) → S% => a;
+}
+static method test2() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = (core::int a, core::int b) → core::int => let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+  d = (a, b) => '\$a';
+                    ^" in "${a}" as{TypeError,ForNonNullableByDefault} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.strong.transformed.expect
new file mode 100644
index 0000000..3de8d0f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+//   d = (a, b) => '$a';
+//                     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object? = dynamic> = (T%, T%) → T%;
+static method test1() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = <S extends core::Object? = dynamic>(S% a, S% b) → S% => a;
+}
+static method test2() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = (core::int a, core::int b) → core::int => let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+  d = (a, b) => '\$a';
+                    ^" in "${a}" as{TypeError,ForNonNullableByDefault} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.textual_outline.expect
new file mode 100644
index 0000000..56fe1c0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef F<T> = T Function(T, T);
+test1() {}
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6091e0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+test1() {}
+test2() {}
+typedef F<T> = T Function(T, T);
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.weak.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.weak.expect
new file mode 100644
index 0000000..3de8d0f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.weak.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+//   d = (a, b) => '$a';
+//                     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object? = dynamic> = (T%, T%) → T%;
+static method test1() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = <S extends core::Object? = dynamic>(S% a, S% b) → S% => a;
+}
+static method test2() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = (core::int a, core::int b) → core::int => let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+  d = (a, b) => '\$a';
+                    ^" in "${a}" as{TypeError,ForNonNullableByDefault} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.weak.transformed.expect
new file mode 100644
index 0000000..3de8d0f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_promoted.dart.weak.transformed.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+//   d = (a, b) => '$a';
+//                     ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant T extends core::Object? = dynamic> = (T%, T%) → T%;
+static method test1() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = <S extends core::Object? = dynamic>(S% a, S% b) → S% => a;
+}
+static method test2() → dynamic {
+  dynamic d = (core::int a, core::int b) → core::int => a;
+  d as{ForNonNullableByDefault} (core::int, core::int) → core::int;
+  d = (core::int a, core::int b) → core::int => let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/infer_from_promoted.dart:16:21: Error: A value of type 'String' can't be returned from a function with return type 'int'.
+  d = (a, b) => '\$a';
+                    ^" in "${a}" as{TypeError,ForNonNullableByDefault} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579.dart b/pkg/front_end/testcases/nnbd/issue42579.dart
new file mode 100644
index 0000000..2541b06
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, 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.
+
+class A<T> {}
+
+S foo<S>() => throw "foo";
+
+bar<R>(A<R> a) {}
+
+baz() => bar(foo());
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42579.dart.outline.expect
new file mode 100644
index 0000000..226d626
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579.dart.outline.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    ;
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  ;
+static method bar<R extends core::Object? = dynamic>(self::A<self::bar::R%> a) → dynamic
+  ;
+static method baz() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue42579.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42579.dart.strong.expect
new file mode 100644
index 0000000..6ee7128
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579.dart.strong.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method bar<R extends core::Object? = dynamic>(self::A<self::bar::R%> a) → dynamic {}
+static method baz() → dynamic
+  return self::bar<core::Object?>(self::foo<self::A<core::Object?>>());
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42579.dart.strong.transformed.expect
new file mode 100644
index 0000000..6ee7128
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method bar<R extends core::Object? = dynamic>(self::A<self::bar::R%> a) → dynamic {}
+static method baz() → dynamic
+  return self::bar<core::Object?>(self::foo<self::A<core::Object?>>());
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42579.dart.weak.expect
new file mode 100644
index 0000000..6ee7128
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579.dart.weak.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method bar<R extends core::Object? = dynamic>(self::A<self::bar::R%> a) → dynamic {}
+static method baz() → dynamic
+  return self::bar<core::Object?>(self::foo<self::A<core::Object?>>());
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42579.dart.weak.transformed.expect
new file mode 100644
index 0000000..6ee7128
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579.dart.weak.transformed.expect
@@ -0,0 +1,15 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method bar<R extends core::Object? = dynamic>(self::A<self::bar::R%> a) → dynamic {}
+static method baz() → dynamic
+  return self::bar<core::Object?>(self::foo<self::A<core::Object?>>());
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_2.dart b/pkg/front_end/testcases/nnbd/issue42579_2.dart
new file mode 100644
index 0000000..2624bf7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_2.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2020, 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.
+
+class A<T> {
+  T get property => throw "A.property";
+}
+
+S foo<S>() => throw "foo";
+
+wrap<R>(R Function() f) {}
+
+wrap2<R>(A<R> Function() f) {}
+
+bar() {
+  A().property.unknown();
+  foo().unknown();
+  wrap(() => foo()..unknown());
+  wrap2(() => foo()..property?.unknown());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_2.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42579_2.dart.outline.expect
new file mode 100644
index 0000000..8ef9e6d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_2.dart.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    ;
+  get property() → self::A::T%
+    ;
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  ;
+static method wrap<R extends core::Object? = dynamic>(() → self::wrap::R% f) → dynamic
+  ;
+static method wrap2<R extends core::Object? = dynamic>(() → self::A<self::wrap2::R%> f) → dynamic
+  ;
+static method bar() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue42579_2.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42579_2.dart.strong.expect
new file mode 100644
index 0000000..922a2af
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_2.dart.strong.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   wrap2(() => foo()..property?.unknown());
+//                                ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+  get property() → self::A::T%
+    return throw "A.property";
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method wrap<R extends core::Object? = dynamic>(() → self::wrap::R% f) → dynamic {}
+static method wrap2<R extends core::Object? = dynamic>(() → self::A<self::wrap2::R%> f) → dynamic {}
+static method bar() → dynamic {
+  new self::A::•<dynamic>().{self::A::property}.unknown();
+  self::foo<dynamic>().unknown();
+  self::wrap<dynamic>(() → dynamic => let final dynamic #t1 = self::foo<dynamic>() in block {
+    #t1.unknown();
+  } =>#t1);
+  self::wrap2<core::Object?>(() → self::A<core::Object?> => let final self::A<core::Object?> #t2 = self::foo<self::A<core::Object?>>() in block {
+    let final core::Object? #t3 = #t2.{self::A::property} in #t3.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  wrap2(() => foo()..property?.unknown());
+                               ^^^^^^^";
+  } =>#t2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42579_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..922a2af
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_2.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   wrap2(() => foo()..property?.unknown());
+//                                ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+  get property() → self::A::T%
+    return throw "A.property";
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method wrap<R extends core::Object? = dynamic>(() → self::wrap::R% f) → dynamic {}
+static method wrap2<R extends core::Object? = dynamic>(() → self::A<self::wrap2::R%> f) → dynamic {}
+static method bar() → dynamic {
+  new self::A::•<dynamic>().{self::A::property}.unknown();
+  self::foo<dynamic>().unknown();
+  self::wrap<dynamic>(() → dynamic => let final dynamic #t1 = self::foo<dynamic>() in block {
+    #t1.unknown();
+  } =>#t1);
+  self::wrap2<core::Object?>(() → self::A<core::Object?> => let final self::A<core::Object?> #t2 = self::foo<self::A<core::Object?>>() in block {
+    let final core::Object? #t3 = #t2.{self::A::property} in #t3.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  wrap2(() => foo()..property?.unknown());
+                               ^^^^^^^";
+  } =>#t2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_2.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42579_2.dart.weak.expect
new file mode 100644
index 0000000..922a2af
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_2.dart.weak.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   wrap2(() => foo()..property?.unknown());
+//                                ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+  get property() → self::A::T%
+    return throw "A.property";
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method wrap<R extends core::Object? = dynamic>(() → self::wrap::R% f) → dynamic {}
+static method wrap2<R extends core::Object? = dynamic>(() → self::A<self::wrap2::R%> f) → dynamic {}
+static method bar() → dynamic {
+  new self::A::•<dynamic>().{self::A::property}.unknown();
+  self::foo<dynamic>().unknown();
+  self::wrap<dynamic>(() → dynamic => let final dynamic #t1 = self::foo<dynamic>() in block {
+    #t1.unknown();
+  } =>#t1);
+  self::wrap2<core::Object?>(() → self::A<core::Object?> => let final self::A<core::Object?> #t2 = self::foo<self::A<core::Object?>>() in block {
+    let final core::Object? #t3 = #t2.{self::A::property} in #t3.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  wrap2(() => foo()..property?.unknown());
+                               ^^^^^^^";
+  } =>#t2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_2.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42579_2.dart.weak.transformed.expect
new file mode 100644
index 0000000..922a2af
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_2.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   wrap2(() => foo()..property?.unknown());
+//                                ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+  get property() → self::A::T%
+    return throw "A.property";
+}
+static method foo<S extends core::Object? = dynamic>() → self::foo::S%
+  return throw "foo";
+static method wrap<R extends core::Object? = dynamic>(() → self::wrap::R% f) → dynamic {}
+static method wrap2<R extends core::Object? = dynamic>(() → self::A<self::wrap2::R%> f) → dynamic {}
+static method bar() → dynamic {
+  new self::A::•<dynamic>().{self::A::property}.unknown();
+  self::foo<dynamic>().unknown();
+  self::wrap<dynamic>(() → dynamic => let final dynamic #t1 = self::foo<dynamic>() in block {
+    #t1.unknown();
+  } =>#t1);
+  self::wrap2<core::Object?>(() → self::A<core::Object?> => let final self::A<core::Object?> #t2 = self::foo<self::A<core::Object?>>() in block {
+    let final core::Object? #t3 = #t2.{self::A::property} in #t3.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_2.dart:19:32: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  wrap2(() => foo()..property?.unknown());
+                               ^^^^^^^";
+  } =>#t2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_3.dart b/pkg/front_end/testcases/nnbd/issue42579_3.dart
new file mode 100644
index 0000000..0eb607f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_3.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, 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.
+
+class A<X> {}
+
+class B<Y1, Y2 extends List<Y3>, Y3> extends A<Y1> {
+  Y1 get y1 => throw "B.y1";
+  Y2 get y2 => throw "B.y2";
+  Y3 get y3 => throw "B.y3";
+}
+
+foo<Z>(A<List<Z>> Function() f) {}
+
+bar() {
+  foo(() => B()..y1[0]?.unknown());
+  foo(() => B()..y2[0]?.unknown());
+  foo(() => B()..y3?.unknown());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_3.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42579_3.dart.outline.expect
new file mode 100644
index 0000000..51b67d5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_3.dart.outline.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    ;
+}
+class B<Y1 extends core::Object? = dynamic, Y2 extends core::List<self::B::Y3%> = core::List<dynamic>, Y3 extends core::Object? = dynamic> extends self::A<self::B::Y1%> {
+  synthetic constructor •() → self::B<self::B::Y1%, self::B::Y2, self::B::Y3%>
+    ;
+  get y1() → self::B::Y1%
+    ;
+  get y2() → self::B::Y2
+    ;
+  get y3() → self::B::Y3%
+    ;
+}
+static method foo<Z extends core::Object? = dynamic>(() → self::A<core::List<self::foo::Z%>> f) → dynamic
+  ;
+static method bar() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/issue42579_3.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42579_3.dart.strong.expect
new file mode 100644
index 0000000..9c59159
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_3.dart.strong.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y1[0]?.unknown());
+//                         ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y2[0]?.unknown());
+//                         ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+class B<Y1 extends core::Object? = dynamic, Y2 extends core::List<self::B::Y3%> = core::List<dynamic>, Y3 extends core::Object? = dynamic> extends self::A<self::B::Y1%> {
+  synthetic constructor •() → self::B<self::B::Y1%, self::B::Y2, self::B::Y3%>
+    : super self::A::•()
+    ;
+  get y1() → self::B::Y1%
+    return throw "B.y1";
+  get y2() → self::B::Y2
+    return throw "B.y2";
+  get y3() → self::B::Y3%
+    return throw "B.y3";
+}
+static method foo<Z extends core::Object? = dynamic>(() → self::A<core::List<self::foo::Z%>> f) → dynamic {}
+static method bar() → dynamic {
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t1 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t2 = #t1.{self::B::y1}.{core::List::[]}(0) in #t2.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y1[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t1);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t3 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t4 = #t3.{self::B::y2}.{core::List::[]}(0) in #t4.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y2[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t3);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t5 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final dynamic #t6 = #t5.{self::B::y3} in #t6.{core::Object::==}(null) ?{dynamic} null : #t6.unknown();
+  } =>#t5);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_3.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42579_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..9c59159
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_3.dart.strong.transformed.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y1[0]?.unknown());
+//                         ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y2[0]?.unknown());
+//                         ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+class B<Y1 extends core::Object? = dynamic, Y2 extends core::List<self::B::Y3%> = core::List<dynamic>, Y3 extends core::Object? = dynamic> extends self::A<self::B::Y1%> {
+  synthetic constructor •() → self::B<self::B::Y1%, self::B::Y2, self::B::Y3%>
+    : super self::A::•()
+    ;
+  get y1() → self::B::Y1%
+    return throw "B.y1";
+  get y2() → self::B::Y2
+    return throw "B.y2";
+  get y3() → self::B::Y3%
+    return throw "B.y3";
+}
+static method foo<Z extends core::Object? = dynamic>(() → self::A<core::List<self::foo::Z%>> f) → dynamic {}
+static method bar() → dynamic {
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t1 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t2 = #t1.{self::B::y1}.{core::List::[]}(0) in #t2.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y1[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t1);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t3 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t4 = #t3.{self::B::y2}.{core::List::[]}(0) in #t4.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y2[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t3);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t5 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final dynamic #t6 = #t5.{self::B::y3} in #t6.{core::Object::==}(null) ?{dynamic} null : #t6.unknown();
+  } =>#t5);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_3.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42579_3.dart.weak.expect
new file mode 100644
index 0000000..9c59159
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_3.dart.weak.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y1[0]?.unknown());
+//                         ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y2[0]?.unknown());
+//                         ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+class B<Y1 extends core::Object? = dynamic, Y2 extends core::List<self::B::Y3%> = core::List<dynamic>, Y3 extends core::Object? = dynamic> extends self::A<self::B::Y1%> {
+  synthetic constructor •() → self::B<self::B::Y1%, self::B::Y2, self::B::Y3%>
+    : super self::A::•()
+    ;
+  get y1() → self::B::Y1%
+    return throw "B.y1";
+  get y2() → self::B::Y2
+    return throw "B.y2";
+  get y3() → self::B::Y3%
+    return throw "B.y3";
+}
+static method foo<Z extends core::Object? = dynamic>(() → self::A<core::List<self::foo::Z%>> f) → dynamic {}
+static method bar() → dynamic {
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t1 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t2 = #t1.{self::B::y1}.{core::List::[]}(0) in #t2.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y1[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t1);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t3 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t4 = #t3.{self::B::y2}.{core::List::[]}(0) in #t4.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y2[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t3);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t5 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final dynamic #t6 = #t5.{self::B::y3} in #t6.{core::Object::==}(null) ?{dynamic} null : #t6.unknown();
+  } =>#t5);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42579_3.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42579_3.dart.weak.transformed.expect
new file mode 100644
index 0000000..9c59159
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42579_3.dart.weak.transformed.expect
@@ -0,0 +1,56 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y1[0]?.unknown());
+//                         ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+//  - 'Object' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+//   foo(() => B()..y2[0]?.unknown());
+//                         ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+}
+class B<Y1 extends core::Object? = dynamic, Y2 extends core::List<self::B::Y3%> = core::List<dynamic>, Y3 extends core::Object? = dynamic> extends self::A<self::B::Y1%> {
+  synthetic constructor •() → self::B<self::B::Y1%, self::B::Y2, self::B::Y3%>
+    : super self::A::•()
+    ;
+  get y1() → self::B::Y1%
+    return throw "B.y1";
+  get y2() → self::B::Y2
+    return throw "B.y2";
+  get y3() → self::B::Y3%
+    return throw "B.y3";
+}
+static method foo<Z extends core::Object? = dynamic>(() → self::A<core::List<self::foo::Z%>> f) → dynamic {}
+static method bar() → dynamic {
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t1 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t2 = #t1.{self::B::y1}.{core::List::[]}(0) in #t2.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:16:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y1[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t1);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t3 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final core::Object? #t4 = #t3.{self::B::y2}.{core::List::[]}(0) in #t4.{core::Object::==}(null) ?{dynamic} null : invalid-expression "pkg/front_end/testcases/nnbd/issue42579_3.dart:17:25: Error: The method 'unknown' isn't defined for the class 'Object'.
+ - 'Object' is from 'dart:core'.
+Try correcting the name to the name of an existing method, or defining a method named 'unknown'.
+  foo(() => B()..y2[0]?.unknown());
+                        ^^^^^^^";
+  } =>#t3);
+  self::foo<core::Object?>(() → self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> => let final self::B<core::List<core::Object?>, core::List<core::Object?>, dynamic> #t5 = new self::B::•<core::List<core::Object?>, core::List<core::Object?>, dynamic>() in block {
+    let final dynamic #t6 = #t5.{self::B::y3} in #t6.{core::Object::==}(null) ?{dynamic} null : #t6.unknown();
+  } =>#t5);
+}
+static method main() → dynamic {}
diff --git a/pkg/frontend_server/test/frontend_server_flutter_suite.dart b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
index a5619f6..e3e078a 100644
--- a/pkg/frontend_server/test/frontend_server_flutter_suite.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-import 'dart:async' show Timer;
+import 'dart:async' show StreamSubscription, Timer;
 import 'dart:convert' show jsonEncode;
 import 'dart:io' show File, exitCode;
 import 'dart:isolate' show Isolate, ReceivePort, SendPort;
@@ -190,6 +190,7 @@
 
   // Start the test suite in a new isolate.
   ReceivePort exitPort = new ReceivePort();
+  ReceivePort errorPort = new ReceivePort();
   SuiteConfiguration configuration = new SuiteConfiguration(
     resultsPort.sendPort,
     logsPort.sendPort,
@@ -205,7 +206,12 @@
     print("Running suite");
     Isolate isolate = await Isolate.spawn<SuiteConfiguration>(
         runSuite, configuration,
-        onExit: exitPort.sendPort);
+        onExit: exitPort.sendPort, onError: errorPort.sendPort);
+    bool gotError = false;
+    StreamSubscription errorSubscription = errorPort.listen((message) {
+      gotError = true;
+      logs.add("$message");
+    });
     bool timedOut = false;
     Timer timer = Timer(timeoutDuration, () {
       timedOut = true;
@@ -214,16 +220,17 @@
       isolate.kill(priority: Isolate.immediate);
     });
     await exitPort.first;
+    errorSubscription.cancel();
     timer.cancel();
-    if (!timedOut) {
+    if (!timedOut && !gotError) {
       int seconds = stopwatch.elapsedMilliseconds ~/ 1000;
       print("Suite finished (took ${seconds} seconds)");
     }
-    return timedOut;
+    return timedOut || gotError;
   });
 
   // Wait for isolate to terminate and clean up.
-  bool timeout = await future;
+  bool timeoutOrCrash = await future;
   resultsPort.close();
   logsPort.close();
 
@@ -235,5 +242,5 @@
   print("Log files written to ${resultJsonUri.toFilePath()} and"
       " ${logsJsonUri.toFilePath()}");
 
-  exitCode = timeout ? 1 : 0;
+  exitCode = timeoutOrCrash ? 1 : 0;
 }
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index 7a1036d..2b5aa60 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -18,6 +18,7 @@
 
 import 'package:kernel/transformations/continuation.dart' as cont;
 import 'package:kernel/transformations/empty.dart' as empty;
+import 'package:kernel/transformations/value_class.dart' as valueClass;
 import 'package:kernel/transformations/mixin_full_resolution.dart' as mix;
 import 'package:kernel/type_environment.dart';
 import 'package:kernel/vm/constants_native_effects.dart';
@@ -107,6 +108,9 @@
           enableTripleShift: false,
           errorOnUnevaluatedConstant: false);
       break;
+    case 'value-class':
+      component = valueClass.transformComponent(component);
+      break;
     case 'empty':
       component = empty.transformComponent(component);
       break;
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
new file mode 100644
index 0000000..cc0577e
--- /dev/null
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, 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.
+
+library kernel.transformations.value_class;
+
+import '../ast.dart';
+import '../kernel.dart';
+import '../visitor.dart';
+
+Component transformComponent(Component component) {
+  new ValueClassTransformer().visitComponent(component);
+  return component;
+}
+
+class ValueClassTransformer extends Transformer {}
diff --git a/pkg/kernel/problems.md b/pkg/kernel/problems.md
index 82731a9..f064a3f 100644
--- a/pkg/kernel/problems.md
+++ b/pkg/kernel/problems.md
@@ -17,7 +17,7 @@
 `severity`: An integer representing severity. This should match the index in
 `package:_fe_analyzer_shared/src/messages/severity.dart`.
 
-`uri: A uri that this problems relates to.
+`uri`: A uri that this problems relates to.
 
 These values are subject to change, but this file will be updated along with any
 such changes. On the code-side these are defined in
diff --git a/pkg/status_file/.packages b/pkg/status_file/.packages
deleted file mode 100644
index 4d68a9e..0000000
--- a/pkg/status_file/.packages
+++ /dev/null
@@ -1,5 +0,0 @@
-# Generated by pub on 2017-07-24 16:32:37.651832.
-expect:../expect/lib/
-path:../../third_party/pkg/path/lib/
-args:../../third_party/pkg/args/lib/
-status_file:lib/
diff --git a/pkg/test_runner/lib/bot_results.dart b/pkg/test_runner/lib/bot_results.dart
index 8ae9059..88b2eb1 100644
--- a/pkg/test_runner/lib/bot_results.dart
+++ b/pkg/test_runner/lib/bot_results.dart
@@ -14,6 +14,52 @@
 /// The path to the gsutil script.
 String gsutilPy;
 
+// TODO(karlklose):  Update this class with all fields that
+// are used in pkg/test_runner and the tools/bots scripts and include
+// validation (in particular for fields from extend_results.dart, that are
+// optional but expected in some contexts and should always be all or nothing).
+class Result {
+  final String configuration;
+  final String expectation;
+  final bool matches;
+  final String name;
+  final String outcome;
+  final bool changed;
+  final String commitHash;
+  // TODO(karlklose): this field is unnecessary with extended results and
+  // should be removed.
+  final bool flaked;
+  final bool isFlaky;
+  final String previousOutcome;
+
+  Result(
+      this.configuration,
+      this.name,
+      this.outcome,
+      this.expectation,
+      this.matches,
+      this.changed,
+      this.commitHash,
+      this.isFlaky,
+      this.previousOutcome,
+      [this.flaked = false]);
+
+  Result.fromMap(Map<String, dynamic> map, [Map<String, dynamic> flakinessData])
+      : configuration = map["configuration"] as String,
+        name = map["name"] as String,
+        outcome = map["result"] as String,
+        expectation = map["expected"] as String,
+        matches = map["matches"] as bool,
+        changed = map["changed"] as bool,
+        commitHash = map["commit_hash"] as String,
+        isFlaky = map["flaky"] as bool,
+        previousOutcome = map["previous_result"] as String,
+        flaked = flakinessData != null &&
+            (flakinessData["outcomes"] as List).contains(map["result"]);
+
+  String get key => "$configuration:$name";
+}
+
 /// Cloud storage location containing results.
 const testResultsStoragePath = "gs://dart-test-results/builders";
 
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 59bedc2..b2425ea 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -419,12 +419,8 @@
 
   List<String> computeCompilerArguments(
       TestFile testFile, List<String> vmOptions, List<String> args) {
-    // TODO(#42403) Handle this option if dart2js supports non-nullable asserts
-    // on non-nullable method arguments.
-    var options = testFile.sharedOptions.toList();
-    options.remove('--null-assertions');
     return [
-      ...options,
+      ...testFile.sharedOptions,
       ..._configuration.sharedOptions,
       ..._experimentsArgument(_configuration, testFile),
       ...testFile.dart2jsOptions,
diff --git a/pkg/test_runner/lib/src/fuchsia.dart b/pkg/test_runner/lib/src/fuchsia.dart
index 874ded5..004350b 100644
--- a/pkg/test_runner/lib/src/fuchsia.dart
+++ b/pkg/test_runner/lib/src/fuchsia.dart
@@ -28,11 +28,10 @@
   Process _server;
   String _deviceName;
 
-  static Future<void> publishPackage(
-      int emuCpus, String buildDir, String mode) async {
+  static Future<void> publishPackage(String buildDir, String mode) async {
     if (_inst == null) {
       _inst = FuchsiaEmulator();
-      await _inst._start(emuCpus);
+      await _inst._start();
     }
     await _inst._publishPackage(buildDir, mode);
   }
@@ -48,18 +47,11 @@
             arg.replaceAll(Repository.uri.toFilePath(), '/pkg/data/')));
   }
 
-  Future<void> _start(int emuCpus) async {
+  Future<void> _start() async {
     // Start the emulator.
-    DebugLogger.info('Starting Fuchsia emulator with $emuCpus CPUs');
-    _emu = await Process.start('xvfb-run', [
-      femuTool,
-      '--image',
-      'qemu-x64',
-      '-N',
-      '--headless',
-      '-s',
-      '$emuCpus'
-    ]);
+    DebugLogger.info('Starting Fuchsia emulator');
+    _emu = await Process.start(
+        'xvfb-run', [femuTool, '--image', 'qemu-x64', '-N', '--headless']);
 
     // Wait until the emulator is ready and has a valid device name.
     var deviceNameFuture = Completer<String>();
diff --git a/pkg/test_runner/lib/src/test_configurations.dart b/pkg/test_runner/lib/src/test_configurations.dart
index 32201e8..93de210 100644
--- a/pkg/test_runner/lib/src/test_configurations.dart
+++ b/pkg/test_runner/lib/src/test_configurations.dart
@@ -155,7 +155,7 @@
     }
 
     if (configuration.system == System.fuchsia) {
-      await FuchsiaEmulator.publishPackage(configuration.taskCount,
+      await FuchsiaEmulator.publishPackage(
           configuration.buildDirectory, configuration.mode.name);
     }
   }
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index e971a37..90ee11a 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## 4.2.0
+- Update to version `3.37.0` of the spec.
+- Added `getProcessMemoryUsage` RPC and `ProcessMemoryUsage` and `ProcessMemoryItem` objects.
+- Added `getWebSocketTarget` RPC and `WebSocketTarget` object.
+
 ## 4.1.0
 - Update to version `3.35.0` of the spec.
 - Expose more `@required` parameters on the named constructors of VM service objects.
diff --git a/pkg/vm_service/example/vm_service_assert.dart b/pkg/vm_service/example/vm_service_assert.dart
index 33a518d..8e64c27 100644
--- a/pkg/vm_service/example/vm_service_assert.dart
+++ b/pkg/vm_service/example/vm_service_assert.dart
@@ -940,6 +940,30 @@
   return list;
 }
 
+vms.ProcessMemoryUsage assertProcessMemoryUsage(vms.ProcessMemoryUsage obj) {
+  assertNotNull(obj);
+  assertString(obj.type);
+  assertProcessMemoryItem(obj.root);
+  return obj;
+}
+
+vms.ProcessMemoryItem assertProcessMemoryItem(vms.ProcessMemoryItem obj) {
+  assertNotNull(obj);
+  assertString(obj.name);
+  assertString(obj.description);
+  assertInt(obj.size);
+  assertListOfProcessMemoryItem(obj.children);
+  return obj;
+}
+
+List<vms.ProcessMemoryItem> assertListOfProcessMemoryItem(
+    List<vms.ProcessMemoryItem> list) {
+  for (vms.ProcessMemoryItem elem in list) {
+    assertProcessMemoryItem(elem);
+  }
+  return list;
+}
+
 vms.ReloadReport assertReloadReport(vms.ReloadReport obj) {
   assertNotNull(obj);
   assertString(obj.type);
@@ -1171,3 +1195,10 @@
   assertListOfIsolateGroupRef(obj.isolateGroups);
   return obj;
 }
+
+vms.WebSocketTarget assertWebSocketTarget(vms.WebSocketTarget obj) {
+  assertNotNull(obj);
+  assertString(obj.type);
+  assertString(obj.uri);
+  return obj;
+}
diff --git a/pkg/vm_service/java/.gitignore b/pkg/vm_service/java/.gitignore
index 3e3793d..4370934 100644
--- a/pkg/vm_service/java/.gitignore
+++ b/pkg/vm_service/java/.gitignore
@@ -26,6 +26,7 @@
 src/org/dartlang/vm/service/consumer/InvokeConsumer.java
 src/org/dartlang/vm/service/consumer/KillConsumer.java
 src/org/dartlang/vm/service/consumer/PauseConsumer.java
+src/org/dartlang/vm/service/consumer/ProcessMemoryUsageConsumer.java
 src/org/dartlang/vm/service/consumer/ProtocolListConsumer.java
 src/org/dartlang/vm/service/consumer/ReloadSourcesConsumer.java
 src/org/dartlang/vm/service/consumer/RemoveBreakpointConsumer.java
@@ -41,6 +42,7 @@
 src/org/dartlang/vm/service/consumer/TimestampConsumer.java
 src/org/dartlang/vm/service/consumer/VMConsumer.java
 src/org/dartlang/vm/service/consumer/VersionConsumer.java
+src/org/dartlang/vm/service/consumer/WebSocketTargetConsumer.java
 src/org/dartlang/vm/service/element/AllocationProfile.java
 src/org/dartlang/vm/service/element/BoundField.java
 src/org/dartlang/vm/service/element/BoundVariable.java
@@ -95,6 +97,8 @@
 src/org/dartlang/vm/service/element/NullRef.java
 src/org/dartlang/vm/service/element/Obj.java
 src/org/dartlang/vm/service/element/ObjRef.java
+src/org/dartlang/vm/service/element/ProcessMemoryItem.java
+src/org/dartlang/vm/service/element/ProcessMemoryUsage.java
 src/org/dartlang/vm/service/element/ProfileFunction.java
 src/org/dartlang/vm/service/element/Protocol.java
 src/org/dartlang/vm/service/element/ProtocolList.java
@@ -125,3 +129,4 @@
 src/org/dartlang/vm/service/element/VM.java
 src/org/dartlang/vm/service/element/VMRef.java
 src/org/dartlang/vm/service/element/Version.java
+src/org/dartlang/vm/service/element/WebSocketTarget.java
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index 469b122..8e5109e 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.35
+version=3.37
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 7f843c3..c317c46 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -28,7 +28,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.35.0';
+const String vmServiceVersion = '3.37.0';
 
 /// @optional
 const String optional = 'optional';
@@ -160,6 +160,8 @@
   'ProfileFunction': ProfileFunction.parse,
   'ProtocolList': ProtocolList.parse,
   'Protocol': Protocol.parse,
+  'ProcessMemoryUsage': ProcessMemoryUsage.parse,
+  'ProcessMemoryItem': ProcessMemoryItem.parse,
   'ReloadReport': ReloadReport.parse,
   'RetainingObject': RetainingObject.parse,
   'RetainingPath': RetainingPath.parse,
@@ -184,6 +186,7 @@
   'Version': Version.parse,
   '@VM': VMRef.parse,
   'VM': VM.parse,
+  'WebSocketTarget': WebSocketTarget.parse,
 };
 
 Map<String, List<String>> _methodReturnTypes = {
@@ -209,6 +212,7 @@
   'getScripts': const ['ScriptList'],
   'getObject': const ['Obj'],
   'getRetainingPath': const ['RetainingPath'],
+  'getProcessMemoryUsage': const ['ProcessMemoryUsage'],
   'getStack': const ['Stack'],
   'getSupportedProtocols': const ['ProtocolList'],
   'getSourceReport': const ['SourceReport'],
@@ -217,6 +221,7 @@
   'getVMTimeline': const ['Timeline'],
   'getVMTimelineFlags': const ['TimelineFlags'],
   'getVMTimelineMicros': const ['Timestamp'],
+  'getWebSocketTarget': const ['WebSocketTarget'],
   'pause': const ['Success'],
   'kill': const ['Success'],
   'registerService': const ['Success'],
@@ -722,6 +727,13 @@
   Future<RetainingPath> getRetainingPath(
       String isolateId, String targetId, int limit);
 
+  /// Returns a description of major uses of memory known to the VM.
+  ///
+  /// Adding or removing buckets is considered a backwards-compatible change for
+  /// the purposes of versioning. A client must gracefully handle the removal or
+  /// addition of any bucket.
+  Future<ProcessMemoryUsage> getProcessMemoryUsage();
+
   /// The `getStack` RPC is used to retrieve the current execution stack and
   /// message queue for an isolate. The isolate does not need to be paused.
   ///
@@ -842,6 +854,13 @@
   /// See [Timestamp] and [getVMTimeline].
   Future<Timestamp> getVMTimelineMicros();
 
+  /// The `getWebSocketTarget` RPC returns the web socket URI that should be
+  /// used by VM service clients with WebSocket implementations that do not
+  /// follow redirects (e.g., `dart:html`'s [WebSocket]).
+  ///
+  /// See [WebSocketTarget].
+  Future<WebSocketTarget> getWebSocketTarget();
+
   /// The `pause` RPC is used to interrupt a running isolate. The RPC enqueues
   /// the interrupt request and potentially returns before the isolate is
   /// paused.
@@ -1359,6 +1378,9 @@
             params['limit'],
           );
           break;
+        case 'getProcessMemoryUsage':
+          response = await _serviceImplementation.getProcessMemoryUsage();
+          break;
         case 'getStack':
           response = await _serviceImplementation.getStack(
             params['isolateId'],
@@ -1395,6 +1417,9 @@
         case 'getVMTimelineMicros':
           response = await _serviceImplementation.getVMTimelineMicros();
           break;
+        case 'getWebSocketTarget':
+          response = await _serviceImplementation.getWebSocketTarget();
+          break;
         case 'pause':
           response = await _serviceImplementation.pause(
             params['isolateId'],
@@ -1823,6 +1848,10 @@
           {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
 
   @override
+  Future<ProcessMemoryUsage> getProcessMemoryUsage() =>
+      _call('getProcessMemoryUsage');
+
+  @override
   Future<Stack> getStack(String isolateId) =>
       _call('getStack', {'isolateId': isolateId});
 
@@ -1870,6 +1899,9 @@
   Future<Timestamp> getVMTimelineMicros() => _call('getVMTimelineMicros');
 
   @override
+  Future<WebSocketTarget> getWebSocketTarget() => _call('getWebSocketTarget');
+
+  @override
   Future<Success> pause(String isolateId) =>
       _call('pause', {'isolateId': isolateId});
 
@@ -5885,6 +5917,84 @@
       'protocolName: ${protocolName}, major: ${major}, minor: ${minor}]';
 }
 
+/// Set [getProcessMemoryUsage].
+class ProcessMemoryUsage extends Response {
+  static ProcessMemoryUsage parse(Map<String, dynamic> json) =>
+      json == null ? null : ProcessMemoryUsage._fromJson(json);
+
+  ProcessMemoryItem root;
+
+  ProcessMemoryUsage({
+    @required this.root,
+  });
+
+  ProcessMemoryUsage._fromJson(Map<String, dynamic> json)
+      : super._fromJson(json) {
+    root = createServiceObject(json['root'], const ['ProcessMemoryItem']);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var json = <String, dynamic>{};
+    json['type'] = 'ProcessMemoryUsage';
+    json.addAll({
+      'root': root.toJson(),
+    });
+    return json;
+  }
+
+  String toString() => '[ProcessMemoryUsage type: ${type}, root: ${root}]';
+}
+
+class ProcessMemoryItem {
+  static ProcessMemoryItem parse(Map<String, dynamic> json) =>
+      json == null ? null : ProcessMemoryItem._fromJson(json);
+
+  /// A short name for this bucket of memory.
+  String name;
+
+  /// A longer description for this item.
+  String description;
+
+  /// The amount of memory in bytes. This is a retained size, not a shallow
+  /// size. That is, it includes the size of children.
+  int size;
+
+  /// Subdivisons of this bucket of memory.
+  List<ProcessMemoryItem> children;
+
+  ProcessMemoryItem({
+    @required this.name,
+    @required this.description,
+    @required this.size,
+    @required this.children,
+  });
+
+  ProcessMemoryItem._fromJson(Map<String, dynamic> json) {
+    name = json['name'];
+    description = json['description'];
+    size = json['size'];
+    children = List<ProcessMemoryItem>.from(
+        createServiceObject(json['children'], const ['ProcessMemoryItem']) ??
+            []);
+  }
+
+  Map<String, dynamic> toJson() {
+    var json = <String, dynamic>{};
+    json.addAll({
+      'name': name,
+      'description': description,
+      'size': size,
+      'children': children.map((f) => f.toJson()).toList(),
+    });
+    return json;
+  }
+
+  String toString() => '[ProcessMemoryItem ' //
+      'name: ${name}, description: ${description}, size: ${size}, ' //
+      'children: ${children}]';
+}
+
 class ReloadReport extends Response {
   static ReloadReport parse(Map<String, dynamic> json) =>
       json == null ? null : ReloadReport._fromJson(json);
@@ -7003,3 +7113,32 @@
 
   String toString() => '[VM]';
 }
+
+/// See [getWebSocketTarget]
+class WebSocketTarget extends Response {
+  static WebSocketTarget parse(Map<String, dynamic> json) =>
+      json == null ? null : WebSocketTarget._fromJson(json);
+
+  /// The web socket URI that should be used to connect to the service.
+  String uri;
+
+  WebSocketTarget({
+    @required this.uri,
+  });
+
+  WebSocketTarget._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
+    uri = json['uri'];
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    var json = <String, dynamic>{};
+    json['type'] = 'WebSocketTarget';
+    json.addAll({
+      'uri': uri,
+    });
+    return json;
+  }
+
+  String toString() => '[WebSocketTarget type: ${type}, uri: ${uri}]';
+}
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index 568f09c..6c4cda5 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
 description: >-
   A library to communicate with a service implementing the Dart VM
   service protocol.
-version: 4.1.0
+version: 4.2.0
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index ba1b0fe..02ae7e1 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -1012,6 +1012,7 @@
             'LibraryDependency',
             'Message',
             'ProfileFunction',
+            'ProcessMemoryItem',
             'Protocol',
             'RetainingObject',
             'SourceReportRange',
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index 8394deb..d1171db 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -398,7 +398,7 @@
     RemoveFromPort(port_handle_, di);
   } else if ((old_mask == 0) && (new_mask != 0)) {
     AddToPort(port_handle_, di);
-  } else if ((old_mask != 0) && (new_mask != 0)) {
+  } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) {
     ASSERT(!di->IsListeningSocket());
     RemoveFromPort(port_handle_, di);
     AddToPort(port_handle_, di);
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 435c240..1d7082e 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -38,6 +38,16 @@
 // Note: If this interface is changed please also update
 // sdk/runtime/tools/dartfuzz/ffiapi.dart
 
+int32_t globalVar;
+
+DART_EXPORT void SetGlobalVar(int32_t v) {
+  globalVar = v;
+}
+
+DART_EXPORT int32_t GetGlobalVar() {
+  return globalVar;
+}
+
 // Sums two ints and adds 42.
 // Simple function to test trampolines.
 // Also used for testing argument exception on passing null instead of a Dart
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index d1918b0..e2e87d8 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -9,6 +9,7 @@
 
 #include <errno.h>           // NOLINT
 #include <fcntl.h>           // NOLINT
+#include <lib/fdio/fdio.h>   // NOLINT
 #include <lib/fdio/namespace.h>  // NOLINT
 #include <libgen.h>          // NOLINT
 #include <sys/mman.h>        // NOLINT
@@ -51,8 +52,10 @@
 void File::Close() {
   ASSERT(handle_->fd() >= 0);
   if (handle_->fd() == STDOUT_FILENO) {
-    // If stdout, redirect fd to /dev/null.
-    int null_fd = NO_RETRY_EXPECTED(open("/dev/null", O_WRONLY));
+    // If stdout, redirect fd to Fuchsia's equivalent of /dev/null.
+    auto* null_fdio = fdio_null_create();
+    ASSERT(null_fdio != nullptr);
+    int null_fd = NO_RETRY_EXPECTED(fdio_bind_to_fd(null_fdio, -1, 0));
     ASSERT(null_fd >= 0);
     VOID_NO_RETRY_EXPECTED(dup2(null_fd, handle_->fd()));
     VOID_NO_RETRY_EXPECTED(close(null_fd));
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index ac8ff5c..438aae4 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -976,6 +976,18 @@
 
 #undef CHECK_RESULT
 
+static bool CheckForInvalidPath(const char* path) {
+  // TODO(zichangguo): "\\?\" is a prefix for paths on Windows.
+  // Arguments passed are parsed as an URI. "\\?\" causes problems as a part
+  // of URIs. This is a temporary workaround to prevent VM from crashing.
+  // Issue: https://github.com/dart-lang/sdk/issues/42779
+  if (strncmp(path, "\\\\?\\", 4) == 0) {
+    Syslog::PrintErr("\\\\?\\ prefix is not supported");
+    return false;
+  }
+  return true;
+}
+
 // Observatory assets are not included in a product build.
 #if !defined(PRODUCT)
 extern unsigned int observatory_assets_archive_len;
@@ -1118,6 +1130,9 @@
   // or a valid file path was provided as the first non-flag argument.
   // Otherwise, script_name can be NULL if DartDev should be run.
   if (script_name != nullptr) {
+    if (!CheckForInvalidPath(script_name)) {
+      Platform::Exit(0);
+    }
     try_load_snapshots_lambda();
   }
 
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 4398c1f..42a677b6 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -340,6 +340,39 @@
   return true;
 }
 
+// Explicitly handle VM flags that can be parsed by DartDev's run command.
+bool Options::ProcessVMDebuggingOptions(const char* arg,
+                                        CommandLineOptions* vm_options) {
+#define IS_DEBUG_OPTION(name, arg)                                             \
+  if (strncmp(name, arg, strlen(name)) == 0) {                                 \
+    vm_options->AddArgument(arg);                                              \
+    return true;                                                               \
+  }
+
+// This is an exhaustive set of VM flags that are accepted by 'dart run'. Flags
+// defined in main_options.h do not need to be handled here as they already
+// have handlers generated.
+//
+// NOTE: When updating this list of VM flags, be sure to make the corresponding
+// changes in pkg/dartdev/lib/src/commands/run.dart.
+#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg)                                \
+  V("--enable-asserts", arg)                                                   \
+  V("--pause-isolates-on-exit", arg)                                           \
+  V("--no-pause-isolates-on-exit", arg)                                        \
+  V("--pause-isolates-on-start", arg)                                          \
+  V("--no-pause-isolates-on-start", arg)                                       \
+  V("--pause-isolates-on-unhandled-exception", arg)                            \
+  V("--no-pause-isolates-on-unhandled-exception", arg)                         \
+  V("--warn-on-pause-with-no-debugger", arg)                                   \
+  V("--no-warn-on-pause-with-no-debugger", arg)
+  HANDLE_DARTDEV_VM_DEBUG_OPTIONS(IS_DEBUG_OPTION, arg);
+
+#undef IS_DEBUG_OPTION
+#undef HANDLE_DARTDEV_VM_DEBUG_OPTIONS
+
+  return false;
+}
+
 int Options::target_abi_version_ = Options::kAbiVersionUnset;
 bool Options::ProcessAbiVersionOption(const char* arg,
                                       CommandLineOptions* vm_options) {
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index adfcb5c..90234e0 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -70,7 +70,8 @@
   V(ProcessEnableVmServiceOption)                                              \
   V(ProcessObserveOption)                                                      \
   V(ProcessAbiVersionOption)                                                   \
-  V(ProcessEnableExperimentOption)
+  V(ProcessEnableExperimentOption)                                             \
+  V(ProcessVMDebuggingOptions)
 
 // This enum must match the strings in kSnapshotKindNames in main_options.cc.
 enum SnapshotKind {
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index ec90206..6881e59 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -455,7 +455,7 @@
 void FUNCTION_NAME(Socket_CreateUnixDomainConnect)(Dart_NativeArguments args) {
 #if defined(HOST_OS_WINDOWS) || defined(HOST_OS_FUCHSIA)
   OSError os_error(
-      -1, "Unix domain sockets are only available on linux, android and macos.",
+      -1, "Unix domain sockets are not available on this operating system.",
       OSError::kUnknown);
   Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
 #else
@@ -855,7 +855,7 @@
     Dart_NativeArguments args) {
 #if defined(HOST_OS_WINDOWS)
   OSError os_error(
-      -1, "Unix domain sockets are only available on linux, android and macos.",
+      -1, "Unix domain sockets are not available on this operating system.",
       OSError::kUnknown);
   Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
 #else
@@ -1104,7 +1104,8 @@
           DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
       break;
     default:
-      Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
+      Dart_PropagateError(
+          Dart_NewApiError("option to setOption() is outside expected range"));
       break;
   }
   if (!result) {
@@ -1202,7 +1203,8 @@
       Dart_SetIntegerReturnValue(args, IPPROTO_UDP);
       break;
     default:
-      Dart_PropagateError(Dart_NewApiError("Value outside of expected range"));
+      Dart_PropagateError(Dart_NewApiError(
+          "option to getOptionValue() is outside expected range"));
       break;
   }
 }
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index f074891..2ff8175 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -65,8 +65,8 @@
 
 /// Minimal common interface for 'WebSocket' in [dart:io] and [dart:html].
 abstract class CommonWebSocket {
-  void connect(String address, void onOpen(), void onMessage(dynamic data),
-      void onError(), void onClose());
+  Future<void> connect(WebSocketVMTarget target, void onOpen(),
+      void onMessage(dynamic data), void onError(), void onClose());
   bool get isOpen;
   void send(dynamic data);
   void close();
@@ -135,8 +135,8 @@
     if (!_hasInitiatedConnect) {
       _hasInitiatedConnect = true;
       try {
-        _webSocket.connect(
-            target.networkAddress, _onOpen, _onMessage, _onError, _onClose);
+        await _webSocket.connect(
+            target, _onOpen, _onMessage, _onError, _onClose);
       } catch (_, stack) {
         _webSocket = null;
         var exception = new NetworkRpcException('WebSocket closed');
diff --git a/runtime/observatory/lib/service_html.dart b/runtime/observatory/lib/service_html.dart
index 5c217d7..2bf441f 100644
--- a/runtime/observatory/lib/service_html.dart
+++ b/runtime/observatory/lib/service_html.dart
@@ -5,6 +5,7 @@
 library service_html;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:html';
 import 'dart:typed_data';
 
@@ -16,20 +17,29 @@
 class _HtmlWebSocket implements CommonWebSocket {
   WebSocket _webSocket;
 
-  void connect(String address, void onOpen(), void onMessage(dynamic data),
-      void onError(), void onClose()) {
+  Future<void> connect(WebSocketVMTarget target, void onOpen(),
+      void onMessage(dynamic data), void onError(), void onClose()) async {
     // The VM service will attempt to redirect our websocket connection request
-    // to DDS, but the dart:html WebSocket doesn't follow redirects. If the
-    // 'implicit-redirect' protocol is provided, the VM service will manually
-    // forward traffic to DDS.
-
-    // TODO(bkonyi): uncomment when DDS is re-enabled.
-    // See https://github.com/dart-lang/sdk/issues/42727
-    // const protocols = ['implicit-redirect'];
+    // to DDS, but the dart:html WebSocket doesn't follow redirects. Instead of
+    // relying on a redirect, we'll request the websocket URI from the service.
+    Uri getWebSocketUriRequest = Uri.parse(target.networkAddress);
+    getWebSocketUriRequest =
+        getWebSocketUriRequest.replace(scheme: 'http', pathSegments: [
+      ...getWebSocketUriRequest.pathSegments.where((e) => e != 'ws'),
+      'getWebSocketTarget',
+    ]);
+    final response = json.decode(await HttpRequest.getString(
+      getWebSocketUriRequest.toString(),
+    ));
+    if (!response.containsKey('result') ||
+        !response['result'].containsKey('uri')) {
+      onError();
+      return;
+    }
     _webSocket = new WebSocket(
-      address,
-      // protocols,
+      response['result']['uri'],
     );
+    target.networkAddress = _webSocket.url;
     _webSocket.onClose.listen((CloseEvent) => onClose());
     _webSocket.onError.listen((Event) => onError());
     _webSocket.onOpen.listen((Event) => onOpen());
diff --git a/runtime/observatory/lib/service_io.dart b/runtime/observatory/lib/service_io.dart
index 2ecbbf1..bf21fea 100644
--- a/runtime/observatory/lib/service_io.dart
+++ b/runtime/observatory/lib/service_io.dart
@@ -17,18 +17,18 @@
 class _IOWebSocket implements CommonWebSocket {
   WebSocket _webSocket;
 
-  void connect(String address, void onOpen(), void onMessage(dynamic data),
-      void onError(), void onClose()) {
-    WebSocket.connect(address).then((WebSocket socket) {
-      _webSocket = socket;
+  Future<void> connect(WebSocketVMTarget target, void onOpen(),
+      void onMessage(dynamic data), void onError(), void onClose()) async {
+    try {
+      _webSocket = await WebSocket.connect(target.networkAddress);
       _webSocket.listen(onMessage,
           onError: (dynamic) => onError(),
           onDone: onClose,
           cancelOnError: true);
       onOpen();
-    }).catchError((e, st) {
+    } catch (_) {
       onError();
-    });
+    }
   }
 
   bool get isOpen =>
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 13fa1af..ff51911 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(36));
+    expect(result['minor'], equals(37));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/tests/vm/dart/splay_test.dart b/runtime/tests/vm/dart/splay_test.dart
index f0498a9..47b4ccc 100644
--- a/runtime/tests/vm/dart/splay_test.dart
+++ b/runtime/tests/vm/dart/splay_test.dart
@@ -28,6 +28,7 @@
 // VMOptions=--verify_before_gc --verify_after_gc
 // VMOptions=--verify_store_buffer
 // VMOptions=--stress_write_barrier_elimination
+// VMOptions=--old_gen_heap_size=100
 
 import "dart:math";
 import 'package:benchmark_harness/benchmark_harness.dart';
diff --git a/runtime/tests/vm/dart_2/splay_test.dart b/runtime/tests/vm/dart_2/splay_test.dart
index 1fec471..824fe01 100644
--- a/runtime/tests/vm/dart_2/splay_test.dart
+++ b/runtime/tests/vm/dart_2/splay_test.dart
@@ -28,6 +28,7 @@
 // VMOptions=--verify_before_gc --verify_after_gc
 // VMOptions=--verify_store_buffer
 // VMOptions=--stress_write_barrier_elimination
+// VMOptions=--old_gen_heap_size=100
 
 import "dart:math";
 import 'package:benchmark_harness/benchmark_harness.dart';
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index e372b4a..6a7523f 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -3170,18 +3170,19 @@
       return this;
     }
 
-#if defined(TARGET_ARCH_IS_32_BIT)
-    // Do not erase extending conversions from 32-bit untagged to 64-bit values
-    // because untagged does not specify whether it is signed or not.
-    if ((box_defn->from() == kUntagged) && to() == kUnboxedInt64) {
-      return this;
-    }
-#endif
-
+    // It's safe to discard any other conversions from and then back to the same
+    // integer type.
     if (box_defn->from() == to()) {
       return box_defn->value()->definition();
     }
 
+    // Do not merge conversions where the first starts from Untagged or the
+    // second ends at Untagged, since we expect to see either UnboxedIntPtr
+    // or UnboxedFfiIntPtr as the other type in an Untagged conversion.
+    if ((box_defn->from() == kUntagged) || (to() == kUntagged)) {
+      return this;
+    }
+
     IntConverterInstr* converter = new IntConverterInstr(
         box_defn->from(), representation(), box_defn->value()->CopyWithType(),
         (to() == kUnboxedInt32) ? GetDeoptId() : DeoptId::kNone);
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 3ee05ef..8c76dad 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -7568,6 +7568,8 @@
 
   virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
 
+  virtual void InferRange(RangeAnalysis* analysis, Range* range);
+
   PRINT_OPERANDS_TO_SUPPORT
   ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
@@ -7660,7 +7662,6 @@
     return kUnboxedInt32;
   }
 
-  virtual void InferRange(RangeAnalysis* analysis, Range* range);
   virtual CompileType ComputeType() const;
 
   DECLARE_INSTRUCTION(BinaryInt32Op)
@@ -7748,7 +7749,6 @@
            (speculative_mode_ == other->AsBinaryInt64Op()->speculative_mode_);
   }
 
-  virtual void InferRange(RangeAnalysis* analysis, Range* range);
   virtual CompileType ComputeType() const;
 
   DECLARE_INSTRUCTION(BinaryInt64Op)
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index e95db90..5eb8db8 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -1008,27 +1008,19 @@
   __ popl(temp);
   __ movl(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), temp);
 
-  if (CanExecuteGeneratedCodeInSafepoint()) {
-    __ movl(temp,
-            compiler::Immediate(compiler::target::Thread::exit_through_ffi()));
-    __ TransitionGeneratedToNative(branch, FPREG, temp,
-                                   /*enter_safepoint=*/true);
-    __ call(branch);
-    __ TransitionNativeToGenerated(temp, /*leave_safepoint=*/true);
-  } else {
-    // We cannot trust that this code will be executable within a safepoint.
-    // Therefore we delegate the responsibility of entering/exiting the
-    // safepoint to a stub which in the VM isolate's heap, which will never lose
-    // execute permission.
-    __ movl(temp,
-            compiler::Address(
-                THR, compiler::target::Thread::
-                         call_native_through_safepoint_entry_point_offset()));
+  ASSERT(!CanExecuteGeneratedCodeInSafepoint());
+  // We cannot trust that this code will be executable within a safepoint.
+  // Therefore we delegate the responsibility of entering/exiting the
+  // safepoint to a stub which in the VM isolate's heap, which will never lose
+  // execute permission.
+  __ movl(temp,
+          compiler::Address(
+              THR, compiler::target::Thread::
+                       call_native_through_safepoint_entry_point_offset()));
 
-    // Calls EAX within a safepoint and clobbers EBX.
-    ASSERT(temp == EBX && branch == EAX);
-    __ call(temp);
-  }
+  // Calls EAX within a safepoint and clobbers EBX.
+  ASSERT(temp == EBX && branch == EAX);
+  __ call(temp);
 
   // The x86 calling convention requires floating point values to be returned on
   // the "floating-point stack" (aka. register ST0). We don't use the
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 4983afd..08b481f 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2858,6 +2858,11 @@
   }
 }
 
+void BinaryIntegerOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
+  InferRangeHelper(analysis->GetSmiRange(left()),
+                   analysis->GetSmiRange(right()), range);
+}
+
 void BinarySmiOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
   const Range* right_smi_range = analysis->GetSmiRange(right());
   // TODO(vegorov) completely remove this once GetSmiRange is eliminated.
@@ -2869,16 +2874,6 @@
   InferRangeHelper(analysis->GetSmiRange(left()), right_smi_range, range);
 }
 
-void BinaryInt32OpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
-  InferRangeHelper(analysis->GetSmiRange(left()),
-                   analysis->GetSmiRange(right()), range);
-}
-
-void BinaryInt64OpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
-  InferRangeHelper(left()->definition()->range(),
-                   right()->definition()->range(), range);
-}
-
 void ShiftIntegerOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
   const Range* right_range = RequiredInputRepresentation(1) == kTagged
                                  ? analysis->GetSmiRange(right())
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index a7a1610..1a4d8af 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -1539,6 +1539,118 @@
   }
 }
 
+void DelayAllocations::Optimize(FlowGraph* graph) {
+  // Go through all AllocateObject instructions and move them down to their
+  // dominant use when doing so is sound.
+  DirectChainedHashMap<IdentitySetKeyValueTrait<Instruction*>> moved;
+  for (BlockIterator block_it = graph->reverse_postorder_iterator();
+       !block_it.Done(); block_it.Advance()) {
+    BlockEntryInstr* block = block_it.Current();
+
+    for (ForwardInstructionIterator instr_it(block); !instr_it.Done();
+         instr_it.Advance()) {
+      Definition* def = instr_it.Current()->AsDefinition();
+      if (def != nullptr && (def->IsAllocateObject() || def->IsCreateArray()) &&
+          def->env() == nullptr && !moved.HasKey(def)) {
+        Instruction* use = DominantUse(def);
+        if (use != nullptr && !use->IsPhi() && IsOneTimeUse(use, def)) {
+          instr_it.RemoveCurrentFromGraph();
+          def->InsertBefore(use);
+          moved.Insert(def);
+        }
+      }
+    }
+  }
+}
+
+Instruction* DelayAllocations::DominantUse(Definition* def) {
+  // Find the use that dominates all other uses.
+
+  // Collect all uses.
+  DirectChainedHashMap<IdentitySetKeyValueTrait<Instruction*>> uses;
+  for (Value::Iterator it(def->input_use_list()); !it.Done(); it.Advance()) {
+    Instruction* use = it.Current()->instruction();
+    uses.Insert(use);
+  }
+  for (Value::Iterator it(def->env_use_list()); !it.Done(); it.Advance()) {
+    Instruction* use = it.Current()->instruction();
+    uses.Insert(use);
+  }
+
+  // Find the dominant use.
+  Instruction* dominant_use = nullptr;
+  auto use_it = uses.GetIterator();
+  while (auto use = use_it.Next()) {
+    // Start with the instruction before the use, then walk backwards through
+    // blocks in the dominator chain until we hit the definition or another use.
+    Instruction* instr = nullptr;
+    if (auto phi = (*use)->AsPhi()) {
+      // For phi uses, the dominant use only has to dominate the
+      // predecessor block corresponding to the phi input.
+      ASSERT(phi->InputCount() == phi->block()->PredecessorCount());
+      for (intptr_t i = 0; i < phi->InputCount(); i++) {
+        if (phi->InputAt(i)->definition() == def) {
+          instr = phi->block()->PredecessorAt(i)->last_instruction();
+          break;
+        }
+      }
+      ASSERT(instr != nullptr);
+    } else {
+      instr = (*use)->previous();
+    }
+
+    bool dominated = false;
+    while (instr != def) {
+      if (uses.HasKey(instr)) {
+        // We hit another use.
+        dominated = true;
+        break;
+      }
+      if (auto block = instr->AsBlockEntry()) {
+        instr = block->dominator()->last_instruction();
+      } else {
+        instr = instr->previous();
+      }
+    }
+    if (!dominated) {
+      if (dominant_use != nullptr) {
+        // More than one use reached the definition, which means no use
+        // dominates all other uses.
+        return nullptr;
+      }
+      dominant_use = *use;
+    }
+  }
+
+  return dominant_use;
+}
+
+bool DelayAllocations::IsOneTimeUse(Instruction* use, Definition* def) {
+  // Check that this use is always executed at most once for each execution of
+  // the definition, i.e. that there is no path from the use to itself that
+  // doesn't pass through the definition.
+  BlockEntryInstr* use_block = use->GetBlock();
+  BlockEntryInstr* def_block = def->GetBlock();
+  if (use_block == def_block) return true;
+
+  DirectChainedHashMap<IdentitySetKeyValueTrait<BlockEntryInstr*>> seen;
+  GrowableArray<BlockEntryInstr*> worklist;
+  worklist.Add(use_block);
+
+  while (!worklist.is_empty()) {
+    BlockEntryInstr* block = worklist.RemoveLast();
+    for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
+      BlockEntryInstr* pred = block->PredecessorAt(i);
+      if (pred == use_block) return false;
+      if (pred == def_block) continue;
+      if (seen.HasKey(pred)) continue;
+      seen.Insert(pred);
+      worklist.Add(pred);
+    }
+  }
+  return true;
+}
+
 class LoadOptimizer : public ValueObject {
  public:
   LoadOptimizer(FlowGraph* graph, AliasedSet* aliased_set)
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.h b/runtime/vm/compiler/backend/redundancy_elimination.h
index 84fc7d2..ab09270 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.h
+++ b/runtime/vm/compiler/backend/redundancy_elimination.h
@@ -145,6 +145,16 @@
   FlowGraph* const flow_graph_;
 };
 
+// Move allocations down to their first use. Improves write barrier elimination.
+class DelayAllocations : public AllStatic {
+ public:
+  static void Optimize(FlowGraph* graph);
+
+ private:
+  static Instruction* DominantUse(Definition* def);
+  static bool IsOneTimeUse(Instruction* use, Definition* def);
+};
+
 class CheckStackOverflowElimination : public AllStatic {
  public:
   // For leaf functions with only a single [StackOverflowInstr] we remove it.
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 21d67ff..74cf38e 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -1114,4 +1114,105 @@
   EXPECT(load_field_in_loop2->calls_initializer());
 }
 
+#if !defined(TARGET_ARCH_IA32)
+
+ISOLATE_UNIT_TEST_CASE(DelayAllocations_DelayAcrossCalls) {
+  const char* kScript = R"(
+    class A {
+      dynamic x, y;
+      A(this.x, this.y);
+    }
+
+    int count = 0;
+
+    @pragma("vm:never-inline")
+    dynamic foo(int i) => count++ < 2 ? i : '$i';
+
+    @pragma("vm:never-inline")
+    dynamic use(v) {}
+
+    void test() {
+      A a = new A(foo(1), foo(2));
+      use(a);
+    }
+  )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  const auto& function = Function::Handle(GetFunction(root_library, "test"));
+
+  // Get fields to kDynamicCid guard
+  Invoke(root_library, "test");
+  Invoke(root_library, "test");
+
+  TestPipeline pipeline(function, CompilerPass::kAOT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+  auto entry = flow_graph->graph_entry()->normal_entry();
+
+  StaticCallInstr* call1;
+  StaticCallInstr* call2;
+  AllocateObjectInstr* allocate;
+  StoreInstanceFieldInstr* store1;
+  StoreInstanceFieldInstr* store2;
+
+  ILMatcher cursor(flow_graph, entry, true, ParallelMovesHandling::kSkip);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      {kMatchAndMoveStaticCall, &call1},
+      kMoveGlob,
+      {kMatchAndMoveStaticCall, &call2},
+      kMoveGlob,
+      {kMatchAndMoveAllocateObject, &allocate},
+      {kMatchAndMoveStoreInstanceField, &store1},
+      {kMatchAndMoveStoreInstanceField, &store2},
+  }));
+
+  EXPECT(strcmp(call1->function().UserVisibleNameCString(), "foo") == 0);
+  EXPECT(strcmp(call2->function().UserVisibleNameCString(), "foo") == 0);
+  EXPECT(store1->instance()->definition() == allocate);
+  EXPECT(!store1->ShouldEmitStoreBarrier());
+  EXPECT(store2->instance()->definition() == allocate);
+  EXPECT(!store2->ShouldEmitStoreBarrier());
+}
+
+ISOLATE_UNIT_TEST_CASE(DelayAllocations_DontDelayIntoLoop) {
+  const char* kScript = R"(
+    void test() {
+      Object o = new Object();
+      for (int i = 0; i < 10; i++) {
+        use(o);
+      }
+    }
+
+    @pragma('vm:never-inline')
+    void use(Object o) {
+      print(o.hashCode);
+    }
+  )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  const auto& function = Function::Handle(GetFunction(root_library, "test"));
+
+  TestPipeline pipeline(function, CompilerPass::kAOT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+  auto entry = flow_graph->graph_entry()->normal_entry();
+
+  AllocateObjectInstr* allocate;
+  StaticCallInstr* call;
+
+  ILMatcher cursor(flow_graph, entry, true, ParallelMovesHandling::kSkip);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      {kMatchAndMoveAllocateObject, &allocate},
+      kMoveGlob,
+      kMatchAndMoveBranchTrue,
+      kMoveGlob,
+      {kMatchAndMoveStaticCall, &call},
+  }));
+
+  EXPECT(strcmp(call->function().UserVisibleNameCString(), "use") == 0);
+  EXPECT(call->Receiver()->definition() == allocate);
+}
+
+#endif  // !defined(TARGET_ARCH_IA32)
+
 }  // namespace dart
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index d5e6297..691ef28 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -224,6 +224,15 @@
 #define INVOKE_PASS(Name)                                                      \
   CompilerPass::Get(CompilerPass::k##Name)->Run(pass_state);
 
+#if defined(DART_PRECOMPILER)
+#define INVOKE_PASS_AOT(Name)                                                  \
+  if (mode == kAOT) {                                                          \
+    INVOKE_PASS(Name);                                                         \
+  }
+#else
+#define INVOKE_PASS_AOT(Name)
+#endif
+
 void CompilerPass::RunGraphIntrinsicPipeline(CompilerPassState* pass_state) {
   INVOKE_PASS(AllocateRegistersForGraphIntrinsic);
 }
@@ -241,9 +250,7 @@
   // may open more opportunities for call specialization.
   // Call specialization during inlining may cause more call
   // sites to be discovered and more functions inlined.
-  if (mode == kAOT) {
-    INVOKE_PASS(ApplyClassIds);
-  }
+  INVOKE_PASS_AOT(ApplyClassIds);
   // Optimize (a << b) & c patterns, merge instructions. Must occur
   // before 'SelectRepresentations' which inserts conversion nodes.
   INVOKE_PASS(TryOptimizePatterns);
@@ -272,13 +279,10 @@
   // so it should not be lifted earlier than that pass.
   INVOKE_PASS(DCE);
   INVOKE_PASS(Canonicalize);
+  INVOKE_PASS_AOT(DelayAllocations);
   INVOKE_PASS(EliminateWriteBarriers);
   INVOKE_PASS(FinalizeGraph);
-#if defined(DART_PRECOMPILER)
-  if (mode == kAOT) {
-    INVOKE_PASS(SerializeGraph);
-  }
-#endif
+  INVOKE_PASS_AOT(SerializeGraph);
   if (FLAG_late_round_trip_serialization) {
     INVOKE_PASS(RoundTripSerialization);
   }
@@ -293,12 +297,8 @@
   if (FLAG_early_round_trip_serialization) {
     INVOKE_PASS(RoundTripSerialization);
   }
-#if defined(DART_PRECOMPILER)
-  if (mode == kAOT) {
-    INVOKE_PASS(ApplyClassIds);
-    INVOKE_PASS(TypePropagation);
-  }
-#endif
+  INVOKE_PASS_AOT(ApplyClassIds);
+  INVOKE_PASS_AOT(TypePropagation);
   INVOKE_PASS(ApplyICData);
   INVOKE_PASS(TryOptimizePatterns);
   INVOKE_PASS(SetOuterInliningId);
@@ -316,18 +316,12 @@
   INVOKE_PASS(ConstantPropagation);
   INVOKE_PASS(OptimisticallySpecializeSmiPhis);
   INVOKE_PASS(TypePropagation);
-#if defined(DART_PRECOMPILER)
-  if (mode == kAOT) {
-    // The extra call specialization pass in AOT is able to specialize more
-    // calls after ConstantPropagation, which removes unreachable code, and
-    // TypePropagation, which can infer more accurate types after removing
-    // unreachable code.
-    INVOKE_PASS(ApplyICData);
-  }
-  if (mode == kAOT) {
-    INVOKE_PASS(OptimizeTypedDataAccesses);
-  }
-#endif
+  // The extra call specialization pass in AOT is able to specialize more
+  // calls after ConstantPropagation, which removes unreachable code, and
+  // TypePropagation, which can infer more accurate types after removing
+  // unreachable code.
+  INVOKE_PASS_AOT(ApplyICData);
+  INVOKE_PASS_AOT(OptimizeTypedDataAccesses);
   INVOKE_PASS(WidenSmiToInt32);
   INVOKE_PASS(SelectRepresentations);
   INVOKE_PASS(CSE);
@@ -345,6 +339,7 @@
   // so it should not be lifted earlier than that pass.
   INVOKE_PASS(DCE);
   INVOKE_PASS(Canonicalize);
+  INVOKE_PASS_AOT(DelayAllocations);
   // Repeat branches optimization after DCE, as it could make more
   // empty blocks.
   INVOKE_PASS(OptimizeBranches);
@@ -360,13 +355,9 @@
   INVOKE_PASS(AllocationSinking_DetachMaterializations);
   INVOKE_PASS(EliminateWriteBarriers);
   INVOKE_PASS(FinalizeGraph);
-#if defined(DART_PRECOMPILER)
-  if (mode == kAOT) {
-    // If we are serializing the flow graph, do it now before we start
-    // doing register allocation.
-    INVOKE_PASS(SerializeGraph);
-  }
-#endif
+  // If we are serializing the flow graph, do it now before we start
+  // doing register allocation.
+  INVOKE_PASS_AOT(SerializeGraph);
   if (FLAG_late_round_trip_serialization) {
     INVOKE_PASS(RoundTripSerialization);
   }
@@ -498,6 +489,8 @@
 
 COMPILER_PASS(DCE, { DeadCodeElimination::EliminateDeadCode(flow_graph); });
 
+COMPILER_PASS(DelayAllocations, { DelayAllocations::Optimize(flow_graph); });
+
 COMPILER_PASS(AllocationSinking_Sink, {
   // TODO(vegorov): Support allocation sinking with try-catch.
   if (flow_graph->graph_entry()->catch_entries().is_empty()) {
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index ffda7a6..2897609 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -30,6 +30,7 @@
   V(ComputeSSA)                                                                \
   V(ConstantPropagation)                                                       \
   V(DCE)                                                                       \
+  V(DelayAllocations)                                                          \
   V(DSE)                                                                       \
   V(EliminateDeadPhis)                                                         \
   V(EliminateEnvironments)                                                     \
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 0ac5463..409ab89 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -574,6 +574,25 @@
   DISALLOW_COPY_AND_ASSIGN(IntMap);
 };
 
+template <typename V>
+class IdentitySetKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef V Key;
+  typedef V Value;
+  typedef V Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return reinterpret_cast<intptr_t>(key);
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) { return pair == key; }
+};
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_HASH_MAP_H_
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 23fbc56..b2f4ae4 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -1614,6 +1614,26 @@
   heap_->RecordData(PageSpace::kPageGrowth, grow_heap);
   last_usage_ = after;
 
+  intptr_t max_capacity_in_words = heap_->old_space()->max_capacity_in_words_;
+  if (max_capacity_in_words != 0) {
+    ASSERT(grow_heap >= 0);
+    // Fraction of asymptote used.
+    double f = static_cast<double>(after.CombinedUsedInWords() +
+                                   (kOldPageSizeInWords * grow_heap)) /
+               static_cast<double>(max_capacity_in_words);
+    ASSERT(f >= 0.0);
+    // Increase weight at the high end.
+    f = f * f;
+    // Fraction of asymptote available.
+    f = 1.0 - f;
+    ASSERT(f <= 1.0);
+    // Discount growth more the closer we get to the desired asymptote.
+    grow_heap = static_cast<intptr_t>(grow_heap * f);
+    // Minimum growth step after reaching the asymptote.
+    intptr_t min_step = (2 * MB) / kOldPageSize;
+    grow_heap = Utils::Maximum(min_step, grow_heap);
+  }
+
   RecordUpdate(before, after, grow_heap, "gc");
 }
 
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index b7cb009..6488425 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 36
+#define SERVICE_PROTOCOL_MINOR_VERSION 37
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 39dfd7e..281f21b 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.36
+# Dart VM Service Protocol 3.37
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.36_ of the Dart VM Service Protocol. This
+This document describes of _version 3.37_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -59,6 +59,7 @@
   - [getVMTimeline](#getvmtimeline)
   - [getVMTimelineFlags](#getvmtimelineflags)
   - [getVMTimelineMicros](#getvmtimelinemicros)
+  - [getWebSocketTarget](#getwebsockettarget)
   - [invoke](#invoke)
   - [pause](#pause)
   - [kill](#kill)
@@ -139,6 +140,7 @@
   - [UresolvedSourceLocation](#unresolvedsourcelocation)
   - [Version](#version)
   - [VM](#vm)
+  - [WebSocketTarget](#websockettarget)
 - [Revision History](#revision-history)
 
 ## RPCs, Requests, and Responses
@@ -423,6 +425,8 @@
 the web socket connection request to DDS. If DDS disconnects from the VM service,
 the VM service will once again start accepting incoming web socket connections.
 
+The VM service forwards the web socket connection by issuing a redirect 
+
 ### Protocol Extensions
 
 Middleware like the Dart Development Service have the option of providing
@@ -1140,6 +1144,17 @@
 
 See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
 
+### getWebSocketTarget
+
+```
+WebSocketTarget getWebSocketTarget()
+```
+
+The _getWebSocketTarget_ RPC returns the web socket URI that should be used by VM service clients
+with WebSocket implementations that do not follow redirects (e.g., `dart:html`'s [WebSocket](https://api.dart.dev/dart-html/WebSocket-class.html)).
+
+See [WebSocketTarget](#websockettarget).
+
 ### pause
 
 ```
@@ -3850,6 +3865,17 @@
 }
 ```
 
+### WebSocketTarget
+
+```
+class WebSocketTarget extends Response {
+  // The web socket URI that should be used to connect to the service.
+  string uri;
+}
+```
+
+See [getWebSocketTarget](#getwebsockettarget)
+
 ## Revision History
 
 version | comments
@@ -3894,5 +3920,6 @@
 3.34 | Added `TimelineStreamSubscriptionsUpdate` event which is sent when `setVMTimelineFlags` is invoked.
 3.35 | Added `getSupportedProtocols` RPC and `ProtocolList`, `Protocol` objects.
 3.36 | Added `getProcessMemoryUsage` RPC and `ProcessMemoryUsage` and `ProcessMemoryItem` objects.
+3.37 | Added `getWebSocketTarget` RPC and `WebSocketTarget` object.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index a032fcd..ea136e6 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -124,7 +124,7 @@
   ],
   [
     "dartdev",
-    "../utils/dartdev:generate_dartdev_snapshot",
+    "../utils/dartdev:dartdev",
   ],
   [
     "dartdoc",
@@ -136,7 +136,7 @@
   ],
   [
     "dds",
-    "../utils/dds:generate_dds_snapshot",
+    "../utils/dds:dds",
   ],
   [
     "pub",
@@ -173,7 +173,7 @@
   ],
   [
     "dartdev",
-    "../utils/dartdev:generate_dartdev_snapshot",
+    "../utils/dartdev:dartdev",
   ],
   [
     "dartdevc",
@@ -189,7 +189,7 @@
   ],
   [
     "dds",
-    "../utils/dds:generate_dds_snapshot",
+    "../utils/dds:dds",
   ],
   [
     "kernel_worker",
@@ -808,7 +808,10 @@
 
 # This rule writes the version file.
 action("write_version_file") {
-  visibility = [ ":create_common_sdk" ]
+  visibility = [
+    ":create_common_sdk",
+    "../utils/dartanalyzer:generate_summary_strong",
+  ]
   inputs = [
     "../tools/VERSION",
     "$default_git_folder/logs/HEAD",
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
index bb58063..8038b81 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
@@ -268,9 +268,18 @@
 
 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor);
 
-/// Get the type of a method from an object using the stored signature
-getType(obj) =>
-    JS('', '# == null ? # : #.__proto__.constructor', obj, Object, obj);
+/// Get the type of an object.
+getType(obj) {
+  if (obj == null) return JS('!', '#', Object);
+
+  if (JS<bool>('!', '#.__proto__ == null', obj)) {
+    // Object.create(null) produces a js object without a prototype.
+    // In that case use the version from a js object literal.
+    return JS('!', '#.Object.prototype.constructor', global_);
+  }
+
+  return JS('!', '#.__proto__.constructor', obj);
+}
 
 getLibraryUri(value) => JS('', '#[#]', value, _libraryUri);
 setLibraryUri(f, uri) => JS('', '#[#] = #', f, _libraryUri, uri);
diff --git a/sdk/lib/_internal/vm/bin/vmservice_io.dart b/sdk/lib/_internal/vm/bin/vmservice_io.dart
index aea026b..e84c8f8 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_io.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_io.dart
@@ -222,6 +222,12 @@
 Timer? _registerSignalHandlerTimer;
 
 _registerSignalHandler() {
+  if (VMService().isExiting) {
+    // If the VM started shutting down we don't want to register this signal
+    // handler, otherwise we'll cause the VM to hang after killing the service
+    // isolate.
+    return;
+  }
   _registerSignalHandlerTimer = null;
   if (_signalWatch == null) {
     // Cannot register for signals.
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index d11c945..bcfa586 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -20,6 +20,10 @@
   /// Loads a dynamic library file with local visibility.
   ///
   /// Throws an [ArgumentError] if loading the dynamic library fails.
+  ///
+  /// Calling this function multiple times, even in different isolates, returns
+  /// objects which are equal but not identical. The underlying library is only
+  /// loaded once into the DartVM by the OS.
   external factory DynamicLibrary.open(String name);
 
   /// Looks up a symbol in the [DynamicLibrary] and returns its address in
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index 3070b30..f86652e 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -187,7 +187,7 @@
 /// of that class.
 /// If applied to a class method, or parameter of such,
 /// any method implementing that interface method is also annotated.
-/// I multiple `Since` annotations apply to the same declaration or
+/// If multiple `Since` annotations apply to the same declaration or
 /// parameter, the latest version takes precendence.
 ///
 /// Any use of a marked API may trigger a warning if the using code
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 4cdd14f..10b1918 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -801,10 +801,12 @@
       {sourceAddress, Duration? timeout}) {
     final IOOverrides? overrides = IOOverrides.current;
     if (overrides == null) {
-      if (!isInsecureConnectionAllowed(host)) {
-        throw new SocketException(
-            "Insecure socket connections are disallowed by platform: $host");
-      }
+      // TODO(b/162514236): This breaks internal device lab tests for Fuchsia.
+      //
+      // if (!isInsecureConnectionAllowed(host)) {
+      //   throw new SocketException(
+      //       "Insecure socket connections are disallowed by platform: $host");
+      // }
       return Socket._connect(host, port,
           sourceAddress: sourceAddress, timeout: timeout);
     }
@@ -819,10 +821,12 @@
       {sourceAddress}) {
     final IOOverrides? overrides = IOOverrides.current;
     if (overrides == null) {
-      if (!isInsecureConnectionAllowed(host)) {
-        throw new SocketException(
-            "Insecure socket connections are disallowed by platform: $host");
-      }
+      // TODO(b/162514236): This breaks internal device lab tests for Fuchsia.
+      //
+      // if (!isInsecureConnectionAllowed(host)) {
+      //   throw new SocketException(
+      //       "Insecure socket connections are disallowed by platform: $host");
+      // }
       return Socket._startConnect(host, port, sourceAddress: sourceAddress);
     }
     return overrides.socketStartConnect(host, port,
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 23f555b..840a6e0 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -219,6 +219,8 @@
 
   final devfs = DevFS();
 
+  Uri? vmServiceUri;
+
   Uri? get ddsUri => _ddsUri;
   Uri? _ddsUri;
 
@@ -344,6 +346,19 @@
     return encodeSuccess(message);
   }
 
+  String _getWebSocketTarget(Message message) {
+    Uri uri = ((_ddsUri != null) ? _ddsUri : vmServiceUri)!;
+    uri = uri.replace(scheme: 'ws', pathSegments: [
+      // Strip empty path segment which causes an extra / to be inserted.
+      ...uri.pathSegments.where((e) => e.isNotEmpty),
+      'ws',
+    ]);
+    return encodeResult(message, {
+      'type': 'WebSocketTarget',
+      'uri': uri.toString(),
+    });
+  }
+
   void _addClient(Client client) {
     assert(client.streams.isEmpty);
     assert(client.services.isEmpty);
@@ -764,6 +779,9 @@
       if (message.method == 'getSupportedProtocols') {
         return await _getSupportedProtocols(message);
       }
+      if (message.method == 'getWebSocketTarget') {
+        return _getWebSocketTarget(message);
+      }
       if (devfs.shouldHandleMessage(message)) {
         return await devfs.handleMessage(message);
       }
@@ -808,7 +826,12 @@
 void _onExit() native 'VMService_OnExit';
 
 /// Notify the VM that the server's address has changed.
-void onServerAddressChange(String? address)
+void onServerAddressChange(String? address) {
+  VMService().vmServiceUri = (address != null) ? Uri.parse(address) : null;
+  _onServerAddressChange(address);
+}
+
+void _onServerAddressChange(String? address)
     native 'VMService_OnServerAddressChange';
 
 /// Subscribe to a service stream.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 607fb63..d389741 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -50,31 +50,8 @@
 LanguageFeatures/Triple-Shift/*: Skip # Not migrated to NNBD
 LanguageFeatures/int-to-double/*: Skip # Not migrated to NNBD
 LanguageFeatures/regression/*: Skip # Not migrated to NNBD
-LibTest/collection/DoubleLinkedQueue/*: Skip # Not migrated to NNBD
-LibTest/collection/DoubleLinkedQueueEntry/*: Skip # Not migrated to NNBD
-LibTest/collection/HasNextIterator/*: Skip # Not migrated to NNBD
-LibTest/collection/HashMap/*: Skip # Not migrated to NNBD
-LibTest/collection/HashSet/*: Skip # Not migrated to NNBD
-LibTest/collection/IterableBase/*: Skip # Not migrated to NNBD
-LibTest/collection/IterableMixin/*: Skip # Not migrated to NNBD
-LibTest/collection/LinkedHashMap/*: Skip # Not migrated to NNBD
-LibTest/collection/LinkedHashSet/*: Skip # Not migrated to NNBD
-LibTest/collection/LinkedList/*: Skip # Not migrated to NNBD
-LibTest/collection/LinkedListEntry/*: Skip # Not migrated to NNBD
 LibTest/collection/ListBase/*: Skip # Not migrated to NNBD
 LibTest/collection/ListMixin/*: Skip # Not migrated to NNBD
-LibTest/collection/ListQueue/*: Skip # Not migrated to NNBD
-LibTest/collection/MapBase/*: Skip # Not migrated to NNBD
-LibTest/collection/MapMixin/*: Skip # Not migrated to NNBD
-LibTest/collection/MapView/*: Skip # Not migrated to NNBD
-LibTest/collection/Queue/*: Skip # Not migrated to NNBD
-LibTest/collection/SetBase/*: Skip # Not migrated to NNBD
-LibTest/collection/SetMixin/*: Skip # Not migrated to NNBD
-LibTest/collection/SplayTreeMap/*: Skip # Not migrated to NNBD
-LibTest/collection/SplayTreeSet/*: Skip # Not migrated to NNBD
-LibTest/collection/UnmodifiableListView/*: Skip # Not migrated to NNBD
-LibTest/collection/UnmodifiableMapBase/*: Skip # Not migrated to NNBD
-LibTest/collection/UnmodifiableMapView/*: Skip # Not migrated to NNBD
 LibTest/convert/AsciiCodec/*: Skip # Not migrated to NNBD
 LibTest/convert/AsciiDecoder/*: Skip # Not migrated to NNBD
 LibTest/convert/AsciiEncoder/*: Skip # Not migrated to NNBD
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index c3ddffa..f34b3eb 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -6,6 +6,9 @@
 LibTest/core/Uri/hasEmptyPath_A01_t01: RuntimeError
 LibTest/core/Uri/parse_A05_t01: RuntimeError
 
+[ $arch == simarm64 && $runtime == dart_precompiled ]
+LibTest/async/Stream/Stream.periodic_all_t02: Skip # Issue 42898
+
 [ $compiler != dart2js && $runtime != none && $runtime != vm && !$checked ]
 LibTest/async/Future/catchError_A03_t05: RuntimeError
 
diff --git a/tests/dart2js/effectively_constant_fields_test.dart b/tests/dart2js/effectively_constant_fields_test.dart
index b6f9e35..bf04671 100644
--- a/tests/dart2js/effectively_constant_fields_test.dart
+++ b/tests/dart2js/effectively_constant_fields_test.dart
@@ -70,5 +70,4 @@
   Expect.equals(0, method6(new Class1()));
   Expect.throws(() => method6(null));
   Expect.equals(4, method7(new Class1()));
-  Expect.throws(() => method7(null));
 }
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart
index 2a97336..2212525 100644
--- a/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart
@@ -1,6 +1,6 @@
 class C5 {
   final value = 500;
   const C5();
-
+}
 
 const c5 = const C5();
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart
index 57fc252..8ee64e7 100644
--- a/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart
@@ -1,6 +1,6 @@
 class C6 {
   final value = 501;
   const C6();
-
+}
 
 const c6 = const C6();
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart
index 33794df..8c6f9b5 100644
--- a/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart
@@ -1,6 +1,6 @@
 class C7 {
   final value = 502;
   const C7();
-
+}
 
 const c7 = const C7();
diff --git a/tests/dart2js/native/load_elim_refinement_test.dart b/tests/dart2js/native/load_elim_refinement_test.dart
index ee9dfee..4ec6adc 100644
--- a/tests/dart2js/native/load_elim_refinement_test.dart
+++ b/tests/dart2js/native/load_elim_refinement_test.dart
@@ -5,11 +5,11 @@
 import 'native_testing.dart';
 
 class A {
-  int a;
+  int? a;
 }
 
 class B extends A {
-  int b;
+  int? b;
 }
 
 @pragma('dart2js:noInline')
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib1.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib1.dart
index 3b9163d..83f5706 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib1.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib1.dart
@@ -1,9 +1,9 @@
+// @dart = 2.7
+
 import 'load_in_correct_order_lib4.dart';
 import 'load_in_correct_order_lib5.dart';
 import 'load_in_correct_order_lib7.dart';
 
-// @dart = 2.7
-
 class C1 {
   final a;
   final b;
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib2.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib2.dart
index 92b26b4..e1ed850 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib2.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib2.dart
@@ -1,9 +1,9 @@
+// @dart = 2.7
+
 import 'load_in_correct_order_lib5.dart';
 import 'load_in_correct_order_lib6.dart';
 import 'load_in_correct_order_lib7.dart';
 
-// @dart = 2.7
-
 class C2 {
   final c;
   final d;
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib3.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib3.dart
index 1320396..0aa50ca 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib3.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib3.dart
@@ -1,9 +1,9 @@
+// @dart = 2.7
+
 import 'load_in_correct_order_lib4.dart';
 import 'load_in_correct_order_lib6.dart';
 import 'load_in_correct_order_lib7.dart';
 
-// @dart = 2.7
-
 class C3 {
   final e;
   final f;
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib4.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib4.dart
index e94a037..2d06764 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib4.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib4.dart
@@ -1,8 +1,8 @@
+// @dart = 2.7
+
 class C4 {
   final value = 499;
   const C4();
-
-// @dart = 2.7
 }
 
 const c4 = const C4();
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib5.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib5.dart
index ca4085f..db0345b 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib5.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib5.dart
@@ -1,8 +1,8 @@
+// @dart = 2.7
+
 class C5 {
   final value = 500;
   const C5();
-
-// @dart = 2.7
 }
 
 const c5 = const C5();
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib6.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib6.dart
index 32f0093..a78e3ed 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib6.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib6.dart
@@ -1,8 +1,8 @@
+// @dart = 2.7
+
 class C6 {
   final value = 501;
   const C6();
-
-// @dart = 2.7
 }
 
 const c6 = const C6();
diff --git a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib7.dart b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib7.dart
index 8056e2f..7359834 100644
--- a/tests/dart2js_2/internal/deferred/load_in_correct_order_lib7.dart
+++ b/tests/dart2js_2/internal/deferred/load_in_correct_order_lib7.dart
@@ -1,8 +1,8 @@
+// @dart = 2.7
+
 class C7 {
   final value = 502;
   const C7();
-
-// @dart = 2.7
 }
 
 const c7 = const C7();
diff --git a/tests/ffi/dylib_isolates_test.dart b/tests/ffi/dylib_isolates_test.dart
new file mode 100644
index 0000000..5eb73ef
--- /dev/null
+++ b/tests/ffi/dylib_isolates_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, 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.
+//
+// Test for DynamicLibrary.open behavior on multiple isolates.
+//
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+import 'dart:isolate';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+void main() async {
+  final dl = dlopenPlatformSpecific('ffi_test_functions');
+  final dl2 = dlopenPlatformSpecific('ffi_test_functions');
+  Expect.equals(dl, dl2);
+  Expect.isFalse(identical(dl, dl2));
+
+  final setGlobalVar = dl
+      .lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
+  final getGlobalVar =
+      dl.lookupFunction<Int32 Function(), int Function()>('GetGlobalVar');
+  setGlobalVar(123);
+  Expect.equals(123, getGlobalVar());
+
+  final receivePort = ReceivePort();
+  Isolate.spawn(secondIsolateMain, receivePort.sendPort);
+  await receivePort.first;
+  Expect.equals(42, getGlobalVar());
+}
+
+void secondIsolateMain(SendPort sendPort) {
+  final dl = dlopenPlatformSpecific('ffi_test_functions');
+  final setGlobalVar = dl
+      .lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
+  setGlobalVar(42);
+  sendPort.send('done');
+}
diff --git a/tests/ffi_2/dylib_isolates_test.dart b/tests/ffi_2/dylib_isolates_test.dart
new file mode 100644
index 0000000..5eb73ef
--- /dev/null
+++ b/tests/ffi_2/dylib_isolates_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2020, 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.
+//
+// Test for DynamicLibrary.open behavior on multiple isolates.
+//
+// SharedObjects=ffi_test_functions
+
+import 'dart:ffi';
+import 'dart:isolate';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+void main() async {
+  final dl = dlopenPlatformSpecific('ffi_test_functions');
+  final dl2 = dlopenPlatformSpecific('ffi_test_functions');
+  Expect.equals(dl, dl2);
+  Expect.isFalse(identical(dl, dl2));
+
+  final setGlobalVar = dl
+      .lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
+  final getGlobalVar =
+      dl.lookupFunction<Int32 Function(), int Function()>('GetGlobalVar');
+  setGlobalVar(123);
+  Expect.equals(123, getGlobalVar());
+
+  final receivePort = ReceivePort();
+  Isolate.spawn(secondIsolateMain, receivePort.sendPort);
+  await receivePort.first;
+  Expect.equals(42, getGlobalVar());
+}
+
+void secondIsolateMain(SendPort sendPort) {
+  final dl = dlopenPlatformSpecific('ffi_test_functions');
+  final setGlobalVar = dl
+      .lookupFunction<Void Function(Int32), void Function(int)>('SetGlobalVar');
+  setGlobalVar(42);
+  sendPort.send('done');
+}
diff --git a/tests/language/assign/static_type_test.dart b/tests/language/assign/static_type_test.dart
index 8fba36d..2362a6f 100644
--- a/tests/language/assign/static_type_test.dart
+++ b/tests/language/assign/static_type_test.dart
@@ -13,7 +13,7 @@
 class A {
   static const int c = "String";
   //                   ^^^^^^^^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+  // [analyzer] COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                   ^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
diff --git a/tests/language/compile_time_constant/static2_test.dart b/tests/language/compile_time_constant/static2_test.dart
index 2f6abe6..73b9dc5 100644
--- a/tests/language/compile_time_constant/static2_test.dart
+++ b/tests/language/compile_time_constant/static2_test.dart
@@ -6,7 +6,7 @@
   final int x;
   const A.a1() : x = 'foo';
   //                 ^^^^^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                 ^^^^^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -22,7 +22,7 @@
   // [cfe] The type of parameter 'x', 'String' is not a subtype of the corresponding field's type, 'int'.
   const A.a5(String x) : this.x = x;
   //                              ^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                              ^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -31,7 +31,7 @@
 
 const a1 = const A.a1();
 //         ^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 const a2 = const A.a2('foo');
 //                    ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
@@ -46,10 +46,10 @@
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 const a5 = const A.a5('foo');
 //         ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 const a6 = const A.a6('foo');
 //         ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 //                    ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
diff --git a/tests/language/compile_time_constant/static3_test.dart b/tests/language/compile_time_constant/static3_test.dart
index f9205fd..fff2773 100644
--- a/tests/language/compile_time_constant/static3_test.dart
+++ b/tests/language/compile_time_constant/static3_test.dart
@@ -6,7 +6,7 @@
   final int x;
   const A.a1() : x = 'foo';
   //                 ^^^^^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                 ^^^^^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -22,7 +22,7 @@
   // [cfe] The type of parameter 'x', 'String' is not a subtype of the corresponding field's type, 'int'.
   const A.a5(String x) : this.x = x;
   //                              ^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                              ^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -31,7 +31,7 @@
 
 var a1 = const A.a1();
 //       ^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 var a2 = const A.a2('foo');
 //                  ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
@@ -46,10 +46,10 @@
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 var a5 = const A.a5('foo');
 //       ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 var a6 = const A.a6('foo');
 //       ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 //                  ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
diff --git a/tests/language/compile_time_constant/static_test.dart b/tests/language/compile_time_constant/static_test.dart
index a7fb0a8..d5ebd13 100644
--- a/tests/language/compile_time_constant/static_test.dart
+++ b/tests/language/compile_time_constant/static_test.dart
@@ -8,7 +8,7 @@
 // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
 const int y = 'foo';
 //            ^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
 // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
 //            ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
diff --git a/tests/language/const/init2_test.dart b/tests/language/const/init2_test.dart
index 40b7a8b..65f0aa2 100644
--- a/tests/language/const/init2_test.dart
+++ b/tests/language/const/init2_test.dart
@@ -6,7 +6,7 @@
 const double c = 0.0;
 const double d = intValue;
 //               ^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
 // [cfe] A value of type 'int' can't be assigned to a variable of type 'double'.
 //               ^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
diff --git a/tests/language/nnbd/null_assertions/parameter_checks_test.dart b/tests/language/nnbd/null_assertions/parameter_checks_test.dart
index d841cd44..9376a63 100644
--- a/tests/language/nnbd/null_assertions/parameter_checks_test.dart
+++ b/tests/language/nnbd/null_assertions/parameter_checks_test.dart
@@ -6,6 +6,7 @@
 
 // Requirements=nnbd-weak
 // VMOptions=--enable-asserts
+// dart2jsOptions=--enable-asserts -DcheckString=false
 // SharedOptions=--null-assertions
 
 // Opt out of Null Safety:
@@ -15,32 +16,40 @@
 
 import 'parameter_checks_opted_in.dart';
 
+bool Function(Object) asserted(String name) {
+  if (const bool.fromEnvironment('checkString', defaultValue: true)) {
+    return (e) => e is AssertionError && e.toString().contains("$name != null");
+  } else {
+    return (e) => e is AssertionError;
+  }
+}
+
 main() {
   Expect.throws(() {
     foo1(null);
-  }, (e) => e is AssertionError && e.toString().contains("a != null"));
+  }, asserted("a"));
   Expect.throws(() {
     foo2(1, null);
-  }, (e) => e is AssertionError && e.toString().contains("b != null"));
+  }, asserted("b"));
   Expect.throws(() {
     foo3();
-  }, (e) => e is AssertionError && e.toString().contains("b != null"));
+  }, asserted("b"));
   Expect.throws(() {
     foo3(b: null);
-  }, (e) => e is AssertionError && e.toString().contains("b != null"));
+  }, asserted("b"));
   foo4a<int>(null);
   Expect.throws(() {
     foo4b<int>(null);
-  }, (e) => e is AssertionError && e.toString().contains("a != null"));
+  }, asserted("a"));
   foo5a<int>(null);
   Expect.throws(() {
     foo5b<int>(null);
-  }, (e) => e is AssertionError && e.toString().contains("a != null"));
+  }, asserted("a"));
   foo6a<int, int, int>(null);
   Expect.throws(() {
     foo6b<int, int, int>(null);
-  }, (e) => e is AssertionError && e.toString().contains("a != null"));
+  }, asserted("a"));
   Expect.throws(() {
     bar().call(null);
-  }, (e) => e is AssertionError && e.toString().contains("x != null"));
+  }, asserted("x"));
 }
diff --git a/tests/language/regress/regress31436_test.dart b/tests/language/regress/regress31436_test.dart
index 84abe5c..08c9a0f 100644
--- a/tests/language/regress/regress31436_test.dart
+++ b/tests/language/regress/regress31436_test.dart
@@ -9,15 +9,15 @@
   g = () {
     return [3];
   };
-  assert(g is List<Object> Function());
-  assert(g is! List<int> Function());
+  Expect.isTrue(g is List<Object> Function());
+  Expect.isFalse(g is List<int> Function());
   g().add("hello"); // No runtime error
   List<int> l = [3];
   g = () {
     return l;
   };
-  assert(g is List<Object> Function());
-  assert(g is List<int> Function());
+  Expect.isTrue(g is List<Object> Function());
+  Expect.isTrue(g is List<int> Function());
   Expect.throwsTypeError(() {
     g().add("hello"); // runtime error
   });
@@ -25,9 +25,9 @@
   g = () {
     return o;
   }; // No implicit downcast on the assignment, implicit downcast on the return
-  assert(g is List<Object> Function());
-  assert(g is! List<int> Function());
-  assert(g is Object Function());
+  Expect.isTrue(g is List<Object> Function());
+  Expect.isFalse(g is List<int> Function());
+  Expect.isTrue(g is Object Function());
   g(); // No runtime error;
   o = 3;
   Expect.throwsTypeError(() {
@@ -38,22 +38,22 @@
 void arrow_test() {
   List<Object> Function() g;
   g = () => [3];
-  assert(g is List<Object> Function());
-  assert(g is! List<int> Function());
+  Expect.isTrue(g is List<Object> Function());
+  Expect.isFalse(g is List<int> Function());
   g().add("hello"); // No runtime error
   List<int> l = [3];
   g = () => l;
-  assert(g is List<Object> Function());
-  assert(g is List<int> Function());
+  Expect.isTrue(g is List<Object> Function());
+  Expect.isTrue(g is List<int> Function());
   Expect.throwsTypeError(() {
     g().add("hello"); // runtime error
   });
   dynamic o = l;
   g = () =>
       o; // No implicit downcast on the assignment, implicit downcast on the return
-  assert(g is List<Object> Function());
-  assert(g is! List<int> Function());
-  assert(g is Object Function());
+  Expect.isTrue(g is List<Object> Function());
+  Expect.isFalse(g is List<int> Function());
+  Expect.isTrue(g is Object Function());
   g(); // No runtime error;
   o = 3;
   Expect.throwsTypeError(() {
diff --git a/tests/language/unsorted/external_test.dart b/tests/language/unsorted/external_test.dart
index b18381f..4cddabc 100644
--- a/tests/language/unsorted/external_test.dart
+++ b/tests/language/unsorted/external_test.dart
@@ -13,6 +13,10 @@
   f() {}
 
   Foo() : x = 0;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD
 
   // fields can't be declared external
   external var x01;
@@ -70,13 +74,13 @@
 }
 
 external int t06(int i) { return 1; }
-// [error line 72, column 1, length 8]
+// [error line 76, column 1, length 8]
 // [analyzer] SYNTACTIC_ERROR.EXTERNAL_METHOD_WITH_BODY
 // [cfe] An external or native method can't have a body.
 //                      ^
 // [cfe] An external or native method can't have a body.
 external int t07(int i) => i + 1;
-// [error line 78, column 1, length 8]
+// [error line 82, column 1, length 8]
 // [analyzer] SYNTACTIC_ERROR.EXTERNAL_METHOD_WITH_BODY
 // [cfe] An external or native method can't have a body.
 //                         ^
diff --git a/tests/language_2/assign/static_type_test.dart b/tests/language_2/assign/static_type_test.dart
index 8fba36d..2362a6f 100644
--- a/tests/language_2/assign/static_type_test.dart
+++ b/tests/language_2/assign/static_type_test.dart
@@ -13,7 +13,7 @@
 class A {
   static const int c = "String";
   //                   ^^^^^^^^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+  // [analyzer] COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                   ^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
diff --git a/tests/language_2/compile_time_constant/static2_test.dart b/tests/language_2/compile_time_constant/static2_test.dart
index 2f6abe6..73b9dc5 100644
--- a/tests/language_2/compile_time_constant/static2_test.dart
+++ b/tests/language_2/compile_time_constant/static2_test.dart
@@ -6,7 +6,7 @@
   final int x;
   const A.a1() : x = 'foo';
   //                 ^^^^^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                 ^^^^^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -22,7 +22,7 @@
   // [cfe] The type of parameter 'x', 'String' is not a subtype of the corresponding field's type, 'int'.
   const A.a5(String x) : this.x = x;
   //                              ^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                              ^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -31,7 +31,7 @@
 
 const a1 = const A.a1();
 //         ^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 const a2 = const A.a2('foo');
 //                    ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
@@ -46,10 +46,10 @@
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 const a5 = const A.a5('foo');
 //         ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 const a6 = const A.a6('foo');
 //         ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 //                    ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
diff --git a/tests/language_2/compile_time_constant/static3_test.dart b/tests/language_2/compile_time_constant/static3_test.dart
index f9205fd..fff2773 100644
--- a/tests/language_2/compile_time_constant/static3_test.dart
+++ b/tests/language_2/compile_time_constant/static3_test.dart
@@ -6,7 +6,7 @@
   final int x;
   const A.a1() : x = 'foo';
   //                 ^^^^^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                 ^^^^^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -22,7 +22,7 @@
   // [cfe] The type of parameter 'x', 'String' is not a subtype of the corresponding field's type, 'int'.
   const A.a5(String x) : this.x = x;
   //                              ^
-  // [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+  // [analyzer] COMPILE_TIME_ERROR.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
   // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
   //                              ^
   // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
@@ -31,7 +31,7 @@
 
 var a1 = const A.a1();
 //       ^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 var a2 = const A.a2('foo');
 //                  ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
@@ -46,10 +46,10 @@
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 var a5 = const A.a5('foo');
 //       ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 var a6 = const A.a6('foo');
 //       ^^^^^^^^^^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
 //                  ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
 // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
diff --git a/tests/language_2/compile_time_constant/static_test.dart b/tests/language_2/compile_time_constant/static_test.dart
index a7fb0a8..d5ebd13 100644
--- a/tests/language_2/compile_time_constant/static_test.dart
+++ b/tests/language_2/compile_time_constant/static_test.dart
@@ -8,7 +8,7 @@
 // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
 const int y = 'foo';
 //            ^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
 // [cfe] A value of type 'String' can't be assigned to a variable of type 'int'.
 //            ^^^^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
diff --git a/tests/language_2/const/init2_test.dart b/tests/language_2/const/init2_test.dart
index 40b7a8b..65f0aa2 100644
--- a/tests/language_2/const/init2_test.dart
+++ b/tests/language_2/const/init2_test.dart
@@ -6,7 +6,7 @@
 const double c = 0.0;
 const double d = intValue;
 //               ^^^^^^^^
-// [analyzer] CHECKED_MODE_COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
+// [analyzer] COMPILE_TIME_ERROR.VARIABLE_TYPE_MISMATCH
 // [cfe] A value of type 'int' can't be assigned to a variable of type 'double'.
 //               ^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
diff --git a/tests/lib/js/constructor_parameters_static_test.dart b/tests/lib/js/constructor_parameters_static_test.dart
index 597ce1e..3efa2a2 100644
--- a/tests/lib/js/constructor_parameters_static_test.dart
+++ b/tests/lib/js/constructor_parameters_static_test.dart
@@ -30,8 +30,22 @@
   //                 ^
   // [web] TODO(srujzs): Add error once supported.
 
+  // Factories of an anonymous class can only contain named parameters.
+  external factory Bar.barFactoryPositional(int? a);
+  //                                             ^
+  // [web] TODO(srujzs): Add error once supported.
+  external factory Bar.barFactoryOptional([int? a]);
+  //                                            ^
+  // [web] TODO(srujzs): Add error once supported.
+  external factory Bar.barFactoryMixedOptional(int? a, [int? b]);
+  //                                                ^
+  // [web] TODO(srujzs): Add error once supported.
+  external factory Bar.barFactoryMixedNamed(int? a, {int? b});
+  //                                             ^
+  // [web] TODO(srujzs): Add error once supported.
+
   // Named parameters are okay only for factories of an anonymous class.
-  external factory Bar.barFactory({int? a});
+  external factory Bar.barFactoryNamed({int? a});
 }
 
 @JS()
diff --git a/tests/lib/js/method_call_on_object_test.dart b/tests/lib/js/method_call_on_object_test.dart
new file mode 100644
index 0000000..b8eba441
--- /dev/null
+++ b/tests/lib/js/method_call_on_object_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, 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.
+
+// Tests method calls (typed and dynamic) on various forms of JS objects.
+
+@JS()
+library js_parameters_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+external void eval(String code);
+
+@JS()
+class Foo {
+  external Foo();
+  external dynamic method(int x);
+}
+
+@JS()
+external Foo makeFooLiteral();
+
+@JS()
+external Foo makeFooObjectCreate();
+
+main() {
+  // These examples from based on benchmarks-internal/js
+  eval(r'''
+self.Foo = function Foo() {}
+self.Foo.prototype.method = function(x) { return x + 1; }
+
+self.makeFooLiteral = function() {
+  return {
+    method: function(x) { return x + 1; }
+  }
+}
+
+// Objects created in this way have no prototype.
+self.makeFooObjectCreate = function() {
+  var o = Object.create(null);
+  o.method = function(x) { return x + 1; }
+  return o;
+}
+''');
+
+  var foo = Foo();
+  Expect.equals(2, foo.method(1));
+
+  foo = makeFooLiteral();
+  Expect.equals(2, foo.method(1));
+
+  foo = makeFooObjectCreate();
+  Expect.equals(2, foo.method(1));
+
+  dynamic dynamicFoo = Foo();
+  Expect.equals(2, dynamicFoo.method(1));
+
+  dynamicFoo = makeFooLiteral();
+  Expect.equals(2, dynamicFoo.method(1));
+
+  dynamicFoo = makeFooObjectCreate();
+  Expect.equals(2, dynamicFoo.method(1));
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 87f57d3..8d88c56 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -36,6 +36,7 @@
 [ $csp ]
 isolate/deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode
 js/instanceof_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
+js/method_call_on_object_test: SkipByDesign # Issue 42085.
 js/parameters_test: SkipByDesign # Issue 42085.
 
 [ $compiler != dart2js && $compiler != dartdevk ]
diff --git a/tests/lib_2/js/method_call_on_object_test.dart b/tests/lib_2/js/method_call_on_object_test.dart
new file mode 100644
index 0000000..b8eba441
--- /dev/null
+++ b/tests/lib_2/js/method_call_on_object_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, 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.
+
+// Tests method calls (typed and dynamic) on various forms of JS objects.
+
+@JS()
+library js_parameters_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+external void eval(String code);
+
+@JS()
+class Foo {
+  external Foo();
+  external dynamic method(int x);
+}
+
+@JS()
+external Foo makeFooLiteral();
+
+@JS()
+external Foo makeFooObjectCreate();
+
+main() {
+  // These examples from based on benchmarks-internal/js
+  eval(r'''
+self.Foo = function Foo() {}
+self.Foo.prototype.method = function(x) { return x + 1; }
+
+self.makeFooLiteral = function() {
+  return {
+    method: function(x) { return x + 1; }
+  }
+}
+
+// Objects created in this way have no prototype.
+self.makeFooObjectCreate = function() {
+  var o = Object.create(null);
+  o.method = function(x) { return x + 1; }
+  return o;
+}
+''');
+
+  var foo = Foo();
+  Expect.equals(2, foo.method(1));
+
+  foo = makeFooLiteral();
+  Expect.equals(2, foo.method(1));
+
+  foo = makeFooObjectCreate();
+  Expect.equals(2, foo.method(1));
+
+  dynamic dynamicFoo = Foo();
+  Expect.equals(2, dynamicFoo.method(1));
+
+  dynamicFoo = makeFooLiteral();
+  Expect.equals(2, dynamicFoo.method(1));
+
+  dynamicFoo = makeFooObjectCreate();
+  Expect.equals(2, dynamicFoo.method(1));
+}
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index d17a636..843b50a 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -36,6 +36,7 @@
 [ $csp ]
 isolate/deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode
 js/instanceof_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code
+js/method_call_on_object_test: SkipByDesign # Issue 42085.
 js/parameters_test: SkipByDesign # Issue 42085.
 
 [ $compiler != dart2js && $compiler != dartdevk ]
diff --git a/tests/standalone/io/unix_socket_test.dart b/tests/standalone/io/unix_socket_test.dart
index 0193a5c..05f672c 100644
--- a/tests/standalone/io/unix_socket_test.dart
+++ b/tests/standalone/io/unix_socket_test.dart
@@ -216,6 +216,7 @@
       Expect.fail("Unexpected exception $e is thrown");
     } else {
       Expect.isTrue(e is SocketException);
+      Expect.isTrue(e.toString().contains('not available'));
     }
   }
 }
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index 5eca181..a45b3d0 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -7,6 +7,8 @@
 fragmentation_test: Pass, Slow # GC heavy
 fragmentation_typed_data_test: Pass, Slow # GC heavy
 io/process_sync_test: Pass, Slow # Spawns synchronously subprocesses in sequence.
+io/socket_network_policy_test: Skip # Temporarily disabled.
+io/socket_network_policy_localhost_test: Skip # Temporarily disabled.
 
 [ $compiler == dartkb ]
 no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
diff --git a/tests/standalone_2/io/unix_socket_test.dart b/tests/standalone_2/io/unix_socket_test.dart
index 0193a5c..05f672c 100644
--- a/tests/standalone_2/io/unix_socket_test.dart
+++ b/tests/standalone_2/io/unix_socket_test.dart
@@ -216,6 +216,7 @@
       Expect.fail("Unexpected exception $e is thrown");
     } else {
       Expect.isTrue(e is SocketException);
+      Expect.isTrue(e.toString().contains('not available'));
     }
   }
 }
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index e9477e1..d0291cb 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -98,3 +98,13 @@
 io/many_file_operations_test: SkipSlow
 package/*: SkipByDesign # Launches VMs in interesting ways.
 typed_data_isolate_test: SkipSlow
+
+[ $system == fuchsia ]
+# Fuchsia test runner doesn't support multi-tests yet.
+deny_listed_test: Skip
+io/dart_std_io_pipe_test: Skip
+io/platform_resolved_executable_test: Skip
+io/signals_exception_test: Skip
+io/socket_ipv6_test: Skip
+package/invalid_uri_test: Skip
+regress_29350_test: Skip
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 5eca181..a45b3d0 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -7,6 +7,8 @@
 fragmentation_test: Pass, Slow # GC heavy
 fragmentation_typed_data_test: Pass, Slow # GC heavy
 io/process_sync_test: Pass, Slow # Spawns synchronously subprocesses in sequence.
+io/socket_network_policy_test: Skip # Temporarily disabled.
+io/socket_network_policy_localhost_test: Skip # Temporarily disabled.
 
 [ $compiler == dartkb ]
 no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
diff --git a/tools/VERSION b/tools/VERSION
index d0b396f..df8f5d5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 2
+PRERELEASE 3
 PRERELEASE_PATCH 0
 ABI_VERSION 39
 OLDEST_SUPPORTED_ABI_VERSION 39
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index 8c23405..74aa8e2 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -44,7 +44,6 @@
   - dart2js_full: Boolean indicating whether this builder will run dart2js
     on several different runtimes.
   - builder_tag: A tag indicating a special builder setup.
-  - cps_ir: Run the compiler with the cps based backend
   """
 
     def __init__(self,
@@ -63,8 +62,7 @@
                  arch=None,
                  dart2js_full=False,
                  builder_tag=None,
-                 batch=False,
-                 cps_ir=False):
+                 batch=False):
         self.compiler = compiler
         self.runtime = runtime
         self.mode = mode
@@ -80,7 +78,6 @@
         self.dart2js_full = dart2js_full
         self.builder_tag = builder_tag
         self.batch = batch
-        self.cps_ir = cps_ir
         if (arch == None):
             self.arch = 'ia32'
         else:
diff --git a/tools/bots/compare_results.dart b/tools/bots/compare_results.dart
index 4b64057..ef74e02 100755
--- a/tools/bots/compare_results.dart
+++ b/tools/bots/compare_results.dart
@@ -13,29 +13,6 @@
 import 'package:args/args.dart';
 import 'package:test_runner/bot_results.dart';
 
-class Result {
-  final String configuration;
-  final String name;
-  final String outcome;
-  final String expectation;
-  final bool matches;
-  final bool flaked;
-
-  Result(this.configuration, this.name, this.outcome, this.expectation,
-      this.matches, this.flaked);
-
-  Result.fromMap(Map<String, dynamic> map, Map<String, dynamic> flakinessData)
-      : configuration = map["configuration"],
-        name = map["name"],
-        outcome = map["result"],
-        expectation = map["expected"],
-        matches = map["matches"],
-        flaked = flakinessData != null &&
-            flakinessData["outcomes"].contains(map["result"]);
-
-  String get key => "$configuration:$name";
-}
-
 class Event {
   final Result before;
   final Result after;
diff --git a/tools/bots/lib/src/firestore.dart b/tools/bots/lib/src/firestore.dart
new file mode 100644
index 0000000..6e8cc47
--- /dev/null
+++ b/tools/bots/lib/src/firestore.dart
@@ -0,0 +1,217 @@
+// Copyright (c) 2020, 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 'dart:convert' show jsonDecode, jsonEncode;
+import 'dart:io' show File, HttpStatus;
+
+import 'package:http/http.dart' as http;
+
+Future<String> readGcloudAuthToken(String path) async {
+  String token = await File(path).readAsString();
+  return token.split("\n").first;
+}
+
+/// Helper class to access the Firestore REST API.
+///
+/// This class is not a complete implementation of the Firestore REST protocol
+/// and is only meant to support the operations required by scripts in
+/// tools/bots.
+class FirestoreDatabase {
+  final http.Client _client = http.Client();
+  final String _authToken;
+  final String _project;
+
+  /// The current transaction ID in base64 (or `null`)
+  String _currentTransaction;
+
+  /// Returns the current transaction escaped to be useable as part of a URI.
+  String get _escapedCurrentTransaction {
+    return Uri.encodeFull(_currentTransaction)
+        // The Firestore API does not accept '+' in URIs
+        .replaceAll("+", "%2B");
+  }
+
+  FirestoreDatabase(this._project, this._authToken);
+
+  static const apiUrl = 'https://firestore.googleapis.com/v1beta1';
+
+  String get projectUrl => '$apiUrl/projects/$_project';
+
+  String get documentsUrl => '$projectUrl/databases/(default)/documents';
+
+  String get queryUrl => '$documentsUrl:runQuery';
+
+  Map<String, String> get _headers {
+    return {
+      'Authorization': 'Bearer $_authToken',
+      'Accept': 'application/json',
+      'Content-Type': 'application/json'
+    };
+  }
+
+  Future<List> runQuery(Query query) async {
+    var body = jsonEncode(query.data);
+    var response = await _client.post(queryUrl, headers: _headers, body: body);
+    if (response.statusCode == HttpStatus.ok) {
+      return jsonDecode(response.body);
+    } else {
+      throw _error(response);
+    }
+  }
+
+  Future<Object> getDocument(String collectionName, String documentName) async {
+    var url = '$documentsUrl/$collectionName/$documentName';
+    if (_currentTransaction != null) {
+      url = '$url?transaction=${_escapedCurrentTransaction}';
+    }
+    var response = await _client.get(url, headers: _headers);
+    if (response.statusCode == HttpStatus.ok) {
+      return jsonDecode(response.body);
+    } else {
+      throw _error(response);
+    }
+  }
+
+  Future<Object> updateField(Map document, String field) async {
+    var url = '$apiUrl/${document["name"]}?updateMask.fieldPaths=$field';
+    var response =
+        await _client.patch(url, headers: _headers, body: jsonEncode(document));
+    if (response.statusCode == HttpStatus.ok) {
+      return jsonDecode(response.body);
+    } else {
+      throw _error(response);
+    }
+  }
+
+  void beginTransaction() async {
+    if (_currentTransaction != null) {
+      throw Exception('Error: nested transactions');
+    }
+    var url = '$documentsUrl:beginTransaction';
+    var body = '{"options": {}}';
+    var response = await _client.post(url, headers: _headers, body: body);
+    if (response.statusCode == HttpStatus.ok) {
+      var result = jsonDecode(response.body);
+      _currentTransaction = result['transaction'] as String;
+      if (_currentTransaction == null) {
+        throw Exception("Call returned no transaction identifier");
+      }
+    } else {
+      throw _error(response, message: 'Could not start transaction:');
+    }
+  }
+
+  Future<bool> commit([List<Write> writes]) async {
+    if (_currentTransaction == null) {
+      throw Exception('"commit" called without transaction');
+    }
+    var body = jsonEncode({
+      "writes": writes.map((write) => write.data).toList(),
+      "transaction": "$_currentTransaction"
+    });
+    var url = '$documentsUrl:commit';
+    var response = await _client.post(url, headers: _headers, body: body);
+    _currentTransaction = null;
+    if (response.statusCode == HttpStatus.conflict) {
+      // This HTTP status code corresponds to the ABORTED error code, see
+      // https://cloud.google.com/datastore/docs/concepts/errors and
+      // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto#L137
+      return false;
+    }
+    if (response.statusCode != HttpStatus.ok) {
+      throw _error(response);
+    }
+    return true;
+  }
+
+  Exception _error(http.Response response, {String message: 'Error'}) {
+    throw Exception('$message: ${response.statusCode}: '
+        '${response.reasonPhrase}:\n${response.body}');
+  }
+
+  /// Closes the underlying HTTP client.
+  void closeClient() => _client.close();
+}
+
+abstract class Write {
+  Map get data;
+}
+
+class Update implements Write {
+  final Map data;
+  Update(List<String> updateMask, Map document, {String updateTime})
+      : data = {
+          if (updateTime != null) "currentDocument": {"updateTime": updateTime},
+          "updateMask": {"fieldPaths": updateMask},
+          "update": document
+        };
+}
+
+class Query {
+  final Map data;
+  Query(String collection, Filter filter, {int limit})
+      : data = {
+          'structuredQuery': {
+            'from': [
+              {'collectionId': collection}
+            ],
+            if (limit != null) 'limit': limit,
+            'where': filter.data,
+          }
+        };
+}
+
+class Filter {
+  final Map data;
+  Filter(this.data);
+}
+
+class FieldFilter extends Filter {
+  FieldFilter(String field, String op, String type, Object value)
+      : super({
+          'fieldFilter': {
+            'field': {'fieldPath': field},
+            'op': op,
+            'value': {'$type': value},
+          }
+        });
+}
+
+class Field {
+  final String name;
+  Field(this.name);
+  FieldFilter equals(Value value) {
+    return FieldFilter(name, 'EQUAL', value.type, value.value);
+  }
+
+  FieldFilter greaterOrEqual(Value value) {
+    return FieldFilter(name, 'GREATER_THAN_OR_EQUAL', value.type, value.value);
+  }
+
+  FieldFilter lessOrEqual(Value value) {
+    return FieldFilter(name, 'LESS_THAN_OR_EQUAL', value.type, value.value);
+  }
+
+  FieldFilter contains(Value value) {
+    return FieldFilter(name, 'ARRAY_CONTAINS', value.type, value.value);
+  }
+}
+
+class Value {
+  final String type;
+  final Object value;
+  Value.boolean(bool this.value) : type = 'booleanValue';
+  Value.string(String this.value) : type = 'stringValue';
+  Value.integer(int this.value) : type = 'integerValue';
+}
+
+class CompositeFilter extends Filter {
+  CompositeFilter(String op, List<Filter> parts)
+      : super({
+          'compositeFilter': {
+            'op': op,
+            'filters': parts.map((part) => part.data).toList(),
+          }
+        });
+}
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 1e84bd0..60bc284 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -707,7 +707,7 @@
         "builder-tag": "canary"
       }
     },
-    "dartkp-weak-asserts-(linux|mac)-(debug|product|release)-(simarm64|x64)": {
+    "dartkp-weak-asserts-(linux|mac)-(debug|product|release)-x64": {
       "options": {
         "enable-experiment": [
           "non-nullable"
@@ -722,6 +722,22 @@
         "builder-tag": "vm_nnbd"
       }
     },
+    "dartkp-weak-asserts-(linux|mac)-(debug|product|release)-simarm64": {
+      "options": {
+        "enable-experiment": [
+          "non-nullable"
+        ],
+        "gen-kernel-options": [
+          "--no-sound-null-safety"
+        ],
+        "enable-asserts": true,
+        "use-elf": true,
+        "vm-options": [
+          "--no-sound-null-safety"
+        ],
+        "builder-tag": "vm_nnbd"
+      }
+    },
     "dartkp-weak-asserts-win-(debug|product|release)-(simarm64|x64)": {
       "options": {
         "enable-experiment": [
@@ -761,7 +777,7 @@
         "builder-tag": "vm_nnbd"
       }
     },
-    "dartkp-strong-(linux|mac)-(debug|product|release)-(simarm64|x64)": {
+    "dartkp-strong-(linux|mac)-(debug|product|release)-x64": {
       "options": {
         "enable-experiment": [
           "non-nullable"
@@ -775,6 +791,21 @@
         "builder-tag": "vm_nnbd"
       }
     },
+    "dartkp-strong-(linux|mac)-(debug|product|release)-simarm64": {
+      "options": {
+        "enable-experiment": [
+          "non-nullable"
+        ],
+        "gen-kernel-options": [
+          "--sound-null-safety"
+        ],
+        "use-elf": true,
+        "vm-options": [
+          "--sound-null-safety"
+        ],
+        "builder-tag": "vm_nnbd"
+      }
+    },
     "dartkp-strong-win-(debug|product|release)-(simarm64|x64)": {
       "options": {
         "use-elf": true,
diff --git a/tools/bots/update_blamelists.dart b/tools/bots/update_blamelists.dart
new file mode 100644
index 0000000..3fb3c9d
--- /dev/null
+++ b/tools/bots/update_blamelists.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2020, 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.
+
+// This script is used by the bisection mechanism to update the blamelists
+// of active, non-approved failures which include the commit of the current
+// bisection build.
+
+import 'dart:io';
+
+import 'package:args/args.dart';
+
+import 'lib/src/firestore.dart';
+import 'package:test_runner/bot_results.dart';
+
+const newTest = 'new test';
+const skippedTest = 'skipped';
+
+const maxAttempts = 20;
+
+FirestoreDatabase database;
+
+class ResultRecord {
+  final data;
+
+  ResultRecord(this.data);
+
+  Map field(String name) => data['fields'][name];
+
+  int get blamelistStartIndex {
+    return int.parse(field('blamelist_start_index')['integerValue']);
+  }
+
+  void set blamelistStartIndex(int index) {
+    field('blamelist_start_index')['integerValue'] = '$index';
+  }
+
+  int get blamelistEndIndex {
+    return int.parse(field('blamelist_end_index')['integerValue']);
+  }
+
+  String get result => field('result')['stringValue'];
+
+  String get previousResult => field('previous_result')['stringValue'];
+
+  String get name => field('name')['stringValue'];
+
+  String get updateTime => data['updateTime'];
+}
+
+Query unapprovedActiveFailuresQuery(String configuration) {
+  return Query(
+      'results',
+      CompositeFilter('AND', [
+        Field('approved').equals(Value.boolean(false)),
+        // TODO(karlklose): also search for inactive failures?
+        Field('active_configurations').contains(Value.string(configuration)),
+        // TODO(karlklose): add index to check for blamelist_start_index < ?
+      ]));
+}
+
+Future<int> getCommitIndex(String commit) async {
+  try {
+    Map document = await database.getDocument('commits', commit);
+    var index = document['fields']['index'];
+    if (index['integerValue'] == null) {
+      throw Exception('Expected an integer, but got "$index"');
+    }
+    return int.parse(index['integerValue']);
+  } catch (exception) {
+    print('Could not retrieve index for commit "$commit".\n');
+    rethrow;
+  }
+}
+
+/// Compute if the record should be updated based on the outcomes in the
+/// result record and the new test result.
+bool shouldUpdateRecord(ResultRecord resultRecord, Result testResult) {
+  if (testResult == null || !testResult.matches) {
+    return false;
+  }
+  var baseline = testResult.expectation.toLowerCase();
+  if (resultRecord.previousResult.toLowerCase() != baseline) {
+    // Currently we only support the case where a bisection run improves the
+    // accuracy of a "Green" -> "Red" result record.
+    return false;
+  }
+  if (resultRecord.result.toLowerCase() == newTest ||
+      resultRecord.result.toLowerCase() == skippedTest) {
+    // Skipped tests are often configuration dependent, so it could be wrong
+    // to generalize their effect for the result record to different
+    // configurations.
+    return false;
+  }
+  return true;
+}
+
+void updateBlameLists(
+    String configuration, String commit, Map<String, Map> testResults) async {
+  int commitIndex = await getCommitIndex(commit);
+  var query = unapprovedActiveFailuresQuery(configuration);
+  bool needsRetry;
+  int attempts = 0;
+  do {
+    needsRetry = false;
+    var documents = (await database.runQuery(query))
+        .where((result) => result['document'] != null)
+        .map((result) => result['document']['name']);
+    for (var documentPath in documents) {
+      await database.beginTransaction();
+      var documentName = documentPath.split('/').last;
+      var result =
+          ResultRecord(await database.getDocument('results', documentName));
+      if (commitIndex < result.blamelistStartIndex ||
+          commitIndex >= result.blamelistEndIndex) {
+        continue;
+      }
+      String name = result.name;
+      var testResultData = testResults['$configuration:$name'];
+      var testResult =
+          testResultData != null ? Result.fromMap(testResultData) : null;
+      if (!shouldUpdateRecord(result, testResult)) {
+        continue;
+      }
+      print('Found result record: $configuration:${result.name}: '
+          '${result.previousResult} -> ${result.result} '
+          'in ${result.blamelistStartIndex}..${result.blamelistEndIndex} '
+          'to update with ${testResult.outcome} at $commitIndex.');
+      // We found a result representation for this test and configuration whose
+      // blamelist includes this results' commit but whose outcome is different
+      // then the outcome in the provided test results.
+      // This means that this commit should not be part of the result
+      // representation and we can update the lower bound of the commit range
+      // and the previous result.
+      var newStartIndex = commitIndex + 1;
+      if (newStartIndex > result.blamelistEndIndex) {
+        print('internal error: inconsistent results; skipping results entry');
+        continue;
+      }
+      result.blamelistStartIndex = newStartIndex;
+      var updateIndex = Update(['blamelist_start_index'], result.data);
+      if (!await database.commit([updateIndex])) {
+        // Commiting the change to the database had a conflict, retry.
+        needsRetry = true;
+        if (++attempts == maxAttempts) {
+          throw Exception('Exceeded maximum retry attempts ($maxAttempts).');
+        }
+        print('Transaction failed, trying again!');
+      }
+    }
+  } while (needsRetry);
+}
+
+main(List<String> arguments) async {
+  var parser = ArgParser()
+    ..addOption('auth-token',
+        abbr: 'a',
+        help: 'path to a file containing the gcloud auth token (required)')
+    ..addOption('results',
+        abbr: 'r',
+        help: 'path to a file containing the test results (required)')
+    ..addFlag('staging',
+        abbr: 's',
+        help: 'use staging database',
+        defaultsTo: true,
+        negatable: true);
+  var options = parser.parse(arguments);
+  if (options.rest.isNotEmpty ||
+      options['results'] == null ||
+      options['auth-token'] == null) {
+    print(parser.usage);
+    exit(1);
+  }
+  var results = await loadResultsMap(options['results']);
+  if (results.isEmpty) {
+    print("No test results provided, nothing to update.");
+    return;
+  }
+  // Pick an arbitrary result entry to find configuration and commit hash.
+  var firstResult = Result.fromMap(results.values.first);
+  var commit = firstResult.commitHash;
+  var configuration = firstResult.configuration;
+  var project = options['staging'] ? 'dart-ci-staging' : 'dart-ci';
+  database = FirestoreDatabase(
+      project, await readGcloudAuthToken(options['auth-token']));
+  await updateBlameLists(configuration, commit, results);
+  database.closeClient();
+}
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
index 48c9dcf..78c84b0 100644
--- a/utils/dartanalyzer/BUILD.gn
+++ b/utils/dartanalyzer/BUILD.gn
@@ -38,7 +38,11 @@
                             ],
                             "list lines")
 
-prebuilt_dart_action("generate_summary_strong") {
+dart_action("generate_summary_strong") {
+  deps = [
+    "../../sdk:copy_libraries",
+    "../../sdk:write_version_file",
+  ]
   script = "../../pkg/analyzer/tool/summary/build_sdk_summaries.dart"
   packages = "../../.packages"
   inputs = sdk_lib_files + analyzer_files
@@ -48,6 +52,6 @@
   args = [
     "build",
     rebase_path(output),
-    rebase_path("../../sdk"),
+    rebase_path("$root_out_dir/dart-sdk"),
   ]
 }
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index 68a779e..b7ed0c2 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -18,12 +18,12 @@
                             ],
                             "list lines")
 group("dartdev") {
-  deps = [ ":copy_dartdev_snapshot" ]
+  public_deps = [ ":copy_dartdev_snapshot" ]
 }
 
 copy("copy_dartdev_snapshot") {
   visibility = [ ":dartdev" ]
-  deps = [ ":generate_dartdev_snapshot" ]
+  public_deps = [ ":generate_dartdev_snapshot" ]
   sources = [ "$root_gen_dir/dartdev.dart.snapshot" ]
   outputs = [ "$root_out_dir/dartdev.dart.snapshot" ]
 }
@@ -31,6 +31,7 @@
 application_snapshot("generate_dartdev_snapshot") {
   main_dart = "../../pkg/dartdev/bin/dartdev.dart"
   training_args = [ "--help" ]
+  deps = [ "../dds:dds" ]
   inputs = dartdev_files + dartfix_files
   output = "$root_gen_dir/dartdev.dart.snapshot"
 }
diff --git a/utils/dds/BUILD.gn b/utils/dds/BUILD.gn
index 001e710..dd76925 100644
--- a/utils/dds/BUILD.gn
+++ b/utils/dds/BUILD.gn
@@ -12,12 +12,12 @@
                         "list lines")
 
 group("dds") {
-  deps = [ ":copy_dds_snapshot" ]
+  public_deps = [ ":copy_dds_snapshot" ]
 }
 
 copy("copy_dds_snapshot") {
   visibility = [ ":dds" ]
-  deps = [ ":generate_dds_snapshot" ]
+  public_deps = [ ":generate_dds_snapshot" ]
   sources = [ "$root_gen_dir/dds.dart.snapshot" ]
   outputs = [ "$root_out_dir/dds.dart.snapshot" ]
 }