Version 2.15.0-99.0.dev

Merge commit 'e47850a197c5d2522e67a1b8dd11427829ce6f04' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 3857a2d..9ba9c1e 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-09-10T10:06:41.987732",
+  "generated": "2021-09-10T11:44:31.694550",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -112,7 +112,7 @@
       "name": "async",
       "rootUri": "../third_party/pkg/async",
       "packageUri": "lib/",
-      "languageVersion": "2.12"
+      "languageVersion": "2.14"
     },
     {
       "name": "async_helper",
diff --git a/DEPS b/DEPS
index 5416d53..4d6d801 100644
--- a/DEPS
+++ b/DEPS
@@ -73,7 +73,7 @@
 
   # Revisions of /third_party/* dependencies.
   "args_rev": "3b3f55766af13d895d2020ec001a28e8dc147f91",
-  "async_rev": "ecb3835c5b746f7762327d5f57bdc92e0a2e0450",
+  "async_rev": "c64220396e0fa2f7b380590abfedbd25635cd7a0",
   "bazel_worker_rev": "0885637b037979afbf5bcd05fd748b309fd669c0",
   "benchmark_harness_rev": "c546dbd9f639f75cd2f75de8df2eb9f8ea15e8e7",
   "boolean_selector_rev": "665e6921ab246569420376f827bff4585dff0b14",
@@ -139,7 +139,7 @@
   "process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
   "protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
   "pub_rev": "cd7a43f2109f7e5eb22e73c7f4e15d25fd57598e",
-  "pub_semver_rev": "baeea5ac3503546269d25c66523d4334c784a4f9",
+  "pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
   "resource_rev": "6b79867d0becf5395e5819a75720963b8298e9a7",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
diff --git a/pkg/analysis_server/test/integration/linter/lint_names_test.dart b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
index e30881f..58031e7 100644
--- a/pkg/analysis_server/test/integration/linter/lint_names_test.dart
+++ b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
@@ -2,39 +2,37 @@
 // 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 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer/src/string_source.dart';
+import 'package:analyzer_utilities/package_root.dart';
 import 'package:linter/src/rules.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 
 void main() {
-  // Set prefix for local or bot execution.
-  final pathPrefix =
-      FileSystemEntity.isDirectorySync(path.join('test', 'integration'))
-          ? ''
-          : path.join('pkg', 'analysis_server');
-
   /// Ensure server lint name representations correspond w/ actual lint rules.
   /// See, e.g., https://dart-review.googlesource.com/c/sdk/+/95743.
   group('lint_names', () {
-    var fixFileContents = File(path.join(
-            pathPrefix, 'lib', 'src', 'services', 'linter', 'lint_names.dart'))
-        .readAsStringSync();
-    var parser = CompilationUnitParser();
-    var cu = parser.parse(contents: fixFileContents, name: 'lint_names.dart');
-    var lintNamesClass = cu.declarations
+    var pkgRootPath = path.normalize(packageRoot);
+    var fixFilePath = path.join(pkgRootPath, 'analysis_server', 'lib', 'src',
+        'services', 'linter', 'lint_names.dart');
+    var contextCollection = AnalysisContextCollection(
+      includedPaths: [fixFilePath],
+    );
+    var parseResult = contextCollection
+        .contextFor(fixFilePath)
+        .currentSession
+        .getParsedUnit(fixFilePath) as ParsedUnitResult;
+
+    if (parseResult.errors.isNotEmpty) {
+      throw Exception(parseResult.errors);
+    }
+
+    var lintNamesClass = parseResult.unit.declarations
         .firstWhere((m) => m is ClassDeclaration && m.name.name == 'LintNames');
 
     var collector = _FixCollector();
@@ -63,47 +61,6 @@
   return registeredLints;
 }
 
-class CompilationUnitParser {
-  CompilationUnit parse({required String contents, required String name}) {
-    var reader = CharSequenceReader(contents);
-    var stringSource = StringSource(contents, name);
-    var errorListener = _ErrorListener();
-    var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
-    var scanner = Scanner(stringSource, reader, errorListener)
-      ..configureFeatures(
-        featureSetForOverriding: featureSet,
-        featureSet: featureSet,
-      );
-    var startToken = scanner.tokenize();
-    errorListener.throwIfErrors();
-
-    var parser = Parser(
-      stringSource,
-      errorListener,
-      featureSet: featureSet,
-    );
-    var cu = parser.parseCompilationUnit(startToken);
-    errorListener.throwIfErrors();
-
-    return cu;
-  }
-}
-
-class _ErrorListener implements AnalysisErrorListener {
-  final errors = <AnalysisError>[];
-
-  @override
-  void onError(AnalysisError error) {
-    errors.add(error);
-  }
-
-  void throwIfErrors() {
-    if (errors.isNotEmpty) {
-      throw Exception(errors);
-    }
-  }
-}
-
 class _FixCollector extends GeneralizingAstVisitor<void> {
   final List<String> lintNames = <String>[];
 
diff --git a/pkg/analysis_server/test/stress/replay/replay.dart b/pkg/analysis_server/test/stress/replay/replay.dart
index 5837c7d..da2cae0 100644
--- a/pkg/analysis_server/test/stress/replay/replay.dart
+++ b/pkg/analysis_server/test/stress/replay/replay.dart
@@ -216,7 +216,7 @@
   /// to break the text when building edits.
   List<int> _getBreakOffsets(String text) {
     var breakOffsets = <int>[];
-    var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
+    var featureSet = FeatureSet.latestLanguageVersion();
     var scanner = Scanner(_TestSource(), CharSequenceReader(text),
         error.AnalysisErrorListener.NULL_LISTENER)
       ..configureFeatures(
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
index f03c6aa..88ced1a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -40,12 +40,6 @@
   /// The current language version.
   static final Version currentVersion = Version.parse(_currentVersion);
 
-  /// The language version to use in tests.
-  static final Version testingSdkLanguageVersion = Version.parse('2.10.0');
-
-  /// The latest known language version.
-  static final Version latestSdkLanguageVersion = Version.parse('2.13.0');
-
   /// A map containing information about all known experimental flags.
   static final Map<String, ExperimentalFeature> knownFeatures = _knownFeatures;
 
@@ -73,7 +67,7 @@
       explicitFlags.enabled[(feature as ExperimentalFeature).index] = true;
     }
 
-    var sdkLanguageVersion = latestSdkLanguageVersion;
+    var sdkLanguageVersion = currentVersion;
     var flags = restrictEnableFlagsToVersion(
       sdkLanguageVersion: sdkLanguageVersion,
       explicitEnabledFlags: explicitFlags.enabled,
@@ -130,7 +124,7 @@
   /// the flag appearing last.
   factory ExperimentStatus.fromStrings(List<String> flags) {
     return ExperimentStatus.fromStrings2(
-      sdkLanguageVersion: latestSdkLanguageVersion,
+      sdkLanguageVersion: currentVersion,
       flags: flags,
     );
   }
@@ -165,7 +159,7 @@
 
   factory ExperimentStatus.latestLanguageVersion() {
     return ExperimentStatus.fromStrings2(
-      sdkLanguageVersion: latestSdkLanguageVersion,
+      sdkLanguageVersion: currentVersion,
       flags: [],
     );
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index f89ac53..0e1d054 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -129,6 +129,18 @@
   }
 
   @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    // TODO(srawlins): Also check interface types (TypeName?).
+    super.visitGenericFunctionType(node);
+    var parent = node.parent;
+    if ((parent is AsExpression || parent is IsExpression) &&
+        (parent as Expression).inConstantContext) {
+      _checkForConstWithTypeParameters(
+          node, CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS);
+    }
+  }
+
+  @override
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
     if (node.isConst) {
       TypeName typeName = node.constructorName.type;
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index af1fa6f..c4f5c6a 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1093,6 +1093,8 @@
 
   @override
   DartObjectImpl? visitConstructorReference(ConstructorReference node) {
+    // TODO(srawlins): record type arguments in DartObject as well, as in
+    // [visitFunctionReference] below.
     return _getConstantValue(node, node.constructorName.staticElement);
   }
 
@@ -1106,6 +1108,47 @@
   }
 
   @override
+  DartObjectImpl? visitFunctionReference(FunctionReference node) {
+    var functionResult = node.function.accept(this);
+    if (functionResult == null) {
+      return functionResult;
+    }
+    var typeArgumentList = node.typeArguments;
+    if (typeArgumentList == null) {
+      return functionResult;
+    } else {
+      var typeArguments = <DartType>[];
+      var typeArgumentObjects = <DartObjectImpl>[];
+      for (var typeArgument in typeArgumentList.arguments) {
+        var object = typeArgument.accept(this);
+        if (object == null) {
+          return null;
+        }
+        var typeArgumentType = object.toTypeValue();
+        if (typeArgumentType == null) {
+          return null;
+        }
+        // TODO(srawlins): Test type alias types (`typedef i = int`) used as
+        // type arguments. Possibly change implementation based on
+        // canonicalization rules.
+        typeArguments.add(typeArgumentType);
+        typeArgumentObjects.add(object);
+      }
+      return _dartObjectComputer.typeInstantiate(
+          node, functionResult, typeArguments, typeArgumentObjects);
+    }
+  }
+
+  @override
+  DartObjectImpl visitGenericFunctionType(GenericFunctionType node) {
+    return DartObjectImpl(
+      typeSystem,
+      _typeProvider.typeType,
+      TypeState(node.type),
+    );
+  }
+
+  @override
   DartObjectImpl? visitInstanceCreationExpression(
       InstanceCreationExpression node) {
     if (!node.isConst) {
@@ -2103,6 +2146,24 @@
     return null;
   }
 
+  DartObjectImpl? typeInstantiate(
+    FunctionReference node,
+    DartObjectImpl function,
+    List<DartType> typeArguments,
+    List<DartObjectImpl> typeArgumentObjects,
+  ) {
+    var rawType = function.type;
+    if (rawType is FunctionType) {
+      if (typeArguments.length != rawType.typeFormals.length) {
+        return null;
+      }
+      var type = rawType.instantiate(typeArguments);
+      return function.typeInstantiate(_typeSystem, type, typeArgumentObjects);
+    } else {
+      return null;
+    }
+  }
+
   DartObjectImpl? typeTest(
       IsExpression node, DartObjectImpl? expression, DartObjectImpl? type) {
     if (expression != null && type != null) {
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 14aa28c..24f2212 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -13,7 +13,9 @@
 import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:meta/meta.dart';
 
 /// The state of an object representing a boolean value.
 class BoolState extends InstanceState {
@@ -209,6 +211,10 @@
   /// class.
   bool get isUserDefinedObject => _state is GenericState;
 
+  @visibleForTesting
+  List<DartObjectImpl>? get typeArguments =>
+      (_state as FunctionState)._typeArguments;
+
   @override
   bool operator ==(Object object) {
     if (object is DartObjectImpl) {
@@ -917,6 +923,20 @@
     return null;
   }
 
+  DartObjectImpl? typeInstantiate(
+    TypeSystemImpl typeSystem,
+    FunctionType type,
+    List<DartObjectImpl> typeArguments,
+  ) {
+    var functionState = _state as FunctionState;
+    var element = functionState._element;
+    return DartObjectImpl(
+      typeSystem,
+      type,
+      FunctionState(element, typeArguments: typeArguments),
+    );
+  }
+
   /// Throw an exception if the given [object]'s state does not represent a Type
   /// value.
   void _assertType(DartObjectImpl object) {
@@ -1232,9 +1252,12 @@
   /// The element representing the function being modeled.
   final ExecutableElement? _element;
 
+  final List<DartObjectImpl>? _typeArguments;
+
   /// Initialize a newly created state to represent the function with the given
   /// [element].
-  FunctionState(this._element);
+  FunctionState(this._element, {List<DartObjectImpl>? typeArguments})
+      : _typeArguments = typeArguments;
 
   @override
   int get hashCode => _element == null ? 0 : _element.hashCode;
@@ -1243,8 +1266,28 @@
   String get typeName => "Function";
 
   @override
-  bool operator ==(Object object) =>
-      object is FunctionState && (_element == object._element);
+  bool operator ==(Object object) {
+    if (object is! FunctionState) {
+      return false;
+    }
+    if (_element != object._element) {
+      return false;
+    }
+    var typeArguments = _typeArguments;
+    var otherTypeArguments = object._typeArguments;
+    if (typeArguments == null || otherTypeArguments == null) {
+      return typeArguments == null && otherTypeArguments == null;
+    }
+    if (typeArguments.length != otherTypeArguments.length) {
+      return false;
+    }
+    for (var i = 0; i < typeArguments.length; i++) {
+      if (typeArguments[i] != otherTypeArguments[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
 
   @override
   StringState convertToString() {
@@ -1269,7 +1312,24 @@
       if (rightElement == null) {
         return BoolState.UNKNOWN_VALUE;
       }
-      return BoolState.from(_element == rightElement);
+      if (_element != rightElement) {
+        return BoolState.FALSE_STATE;
+      }
+      var typeArguments = _typeArguments;
+      var otherTypeArguments = rightOperand._typeArguments;
+      if (typeArguments == null || otherTypeArguments == null) {
+        return BoolState.from(
+            typeArguments == null && otherTypeArguments == null);
+      }
+      if (typeArguments.length != otherTypeArguments.length) {
+        return BoolState.FALSE_STATE;
+      }
+      for (var i = 0; i < typeArguments.length; i++) {
+        if (typeArguments[i] != otherTypeArguments[i]) {
+          return BoolState.FALSE_STATE;
+        }
+      }
+      return BoolState.TRUE_STATE;
     }
     return BoolState.FALSE_STATE;
   }
diff --git a/pkg/analyzer/lib/src/error/use_result_verifier.dart b/pkg/analyzer/lib/src/error/use_result_verifier.dart
index fd0eaed..1899064 100644
--- a/pkg/analyzer/lib/src/error/use_result_verifier.dart
+++ b/pkg/analyzer/lib/src/error/use_result_verifier.dart
@@ -52,6 +52,11 @@
   }
 
   void _check(AstNode node, Element element) {
+    if (node.parent is CommentReference) {
+      // Don't flag references in comments.
+      return;
+    }
+
     var annotation = _getUseResultMetadata(element);
     if (annotation == null) {
       return;
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index b53f44c..a33890a 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -8,7 +8,6 @@
 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/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -203,8 +202,8 @@
     return spec;
   }
 
-  static LibraryElementImpl library(AnalysisContext context, String libraryName,
-      {bool isNonNullableByDefault = true}) {
+  static LibraryElementImpl library(
+      AnalysisContext context, String libraryName) {
     String fileName = "/$libraryName.dart";
     CompilationUnitElementImpl unit = compilationUnit(fileName);
     LibraryElementImpl library = LibraryElementImpl(
@@ -213,10 +212,7 @@
       libraryName,
       0,
       libraryName.length,
-      FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: ExperimentStatus.testingSdkLanguageVersion,
-        flags: isNonNullableByDefault ? [EnableString.non_nullable] : [],
-      ),
+      FeatureSet.latestLanguageVersion(),
     );
     library.definingCompilationUnit = unit;
     return library;
diff --git a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
index 4269b08..3c7de8d 100644
--- a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
@@ -28,6 +28,7 @@
   void visitAnnotation(Annotation node) {
     _token(node.atSign);
     node.name.accept(this);
+    node.typeArguments?.accept(this);
     _token(node.period);
     node.constructorName?.accept(this);
     node.arguments?.accept(this);
@@ -234,6 +235,11 @@
   }
 
   @override
+  void visitConstructorReference(ConstructorReference node) {
+    node.constructorName.accept(this);
+  }
+
+  @override
   void visitContinueStatement(ContinueStatement node) {
     _token(node.continueKeyword);
     node.label?.accept(this);
@@ -487,6 +493,12 @@
   }
 
   @override
+  void visitFunctionReference(FunctionReference node) {
+    node.function.accept(this);
+    node.typeArguments?.accept(this);
+  }
+
+  @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     _compilationUnitMember(node);
     _token(node.typedefKeyword);
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index 6a7dec8..afe00a5 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -6,7 +6,6 @@
 import 'dart:collection';
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -674,7 +673,7 @@
           .join()
           .contains('dart_package(null_safety=True');
       if (hasNonNullableFlag) {
-        _enabledExperiments = [EnableString.non_nullable];
+        // Enabled by default.
       } else {
         _languageVersion = Version.parse('2.9.0');
       }
diff --git a/pkg/analyzer/test/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart
index 2ac1bac..36bdc90 100644
--- a/pkg/analyzer/test/dart/analysis/utilities_test.dart
+++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -22,15 +22,14 @@
 
 @reflectiveTest
 class UtilitiesTest with ResourceProviderMixin {
-  FeatureSet get defaultFeatureSet =>
-      FeatureSet.forTesting(sdkVersion: '2.2.2');
-
   test_parseFile_default_resource_provider() {
     String content = '''
 void main() => print('Hello, world!');
     ''';
-    ParseStringResult result = _withTemporaryFile(content,
-        (path) => parseFile(path: path, featureSet: defaultFeatureSet));
+    ParseStringResult result = _withTemporaryFile(
+        content,
+        (path) => parseFile(
+            path: path, featureSet: FeatureSet.latestLanguageVersion()));
     expect(result.content, content);
     expect(result.errors, isEmpty);
     expect(result.lineInfo, isNotNull);
@@ -46,7 +45,7 @@
         content,
         (resourceProvider, path) => parseFile(
             path: path,
-            featureSet: defaultFeatureSet,
+            featureSet: FeatureSet.latestLanguageVersion(),
             resourceProvider: resourceProvider,
             throwIfDiagnostics: false));
     expect(result.content, content);
@@ -66,7 +65,7 @@
       expectedPath = path;
       return parseFile(
           path: path,
-          featureSet: defaultFeatureSet,
+          featureSet: FeatureSet.latestLanguageVersion(),
           resourceProvider: resourceProvider,
           throwIfDiagnostics: false);
     });
@@ -83,12 +82,12 @@
             content,
             (resourceProvider, path) => parseFile(
                 path: path,
-                featureSet: defaultFeatureSet,
+                featureSet: FeatureSet.latestLanguageVersion(),
                 resourceProvider: resourceProvider)),
         throwsA(const TypeMatcher<ArgumentError>()));
   }
 
-  test_parseFile_featureSet_nnbd_off() {
+  test_parseFile_featureSet_language_2_9() {
     String content = '''
 int? f() => 1;
 ''';
@@ -110,19 +109,17 @@
     expect(result.unit.toString(), equals('int? f() => 1;'));
   }
 
-  test_parseFile_featureSet_nnbd_on() {
+  test_parseFile_featureSet_language_latest() {
     String content = '''
 int? f() => 1;
 ''';
-    var featureSet =
-        FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
     ParseStringResult result = _withMemoryFile(
         content,
         (resourceProvider, path) => parseFile(
             path: path,
             resourceProvider: resourceProvider,
             throwIfDiagnostics: false,
-            featureSet: featureSet));
+            featureSet: FeatureSet.latestLanguageVersion()));
     expect(result.content, content);
     expect(result.errors, isEmpty);
     expect(result.lineInfo, isNotNull);
@@ -137,7 +134,7 @@
         content,
         (resourceProvider, path) => parseFile(
             path: path,
-            featureSet: defaultFeatureSet,
+            featureSet: FeatureSet.latestLanguageVersion(),
             resourceProvider: resourceProvider));
     expect(result.content, content);
     expect(result.errors, isEmpty);
@@ -200,10 +197,11 @@
     String content = '''
 int? f() => 1;
 ''';
-    var featureSet =
-        FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
     ParseStringResult result = parseString(
-        content: content, throwIfDiagnostics: false, featureSet: featureSet);
+      content: content,
+      throwIfDiagnostics: false,
+      featureSet: FeatureSet.latestLanguageVersion(),
+    );
     expect(result.content, content);
     expect(result.errors, isEmpty);
     expect(result.lineInfo, isNotNull);
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index e7da3d0..4718ea0 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -2,22 +2,17 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/string_source.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../generated/parser_test_base.dart' show ParserTestCase;
-import '../../generated/test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -943,29 +938,10 @@
 E f() => g;
 ''';
 
-  final featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
-
   CompilationUnit? _unit;
 
   CompilationUnit get unit {
-    if (_unit == null) {
-      GatheringErrorListener listener =
-          GatheringErrorListener(checkRanges: true);
-      var source =
-          StringSource(contents, 'PreviousTokenTest_findPrevious.dart');
-      var scanner = Scanner.fasta(source, listener)
-        ..configureFeatures(
-          featureSetForOverriding: featureSet,
-          featureSet: featureSet,
-        );
-      Token tokens = scanner.tokenize();
-      _unit = Parser(
-        source,
-        listener,
-        featureSet: featureSet,
-      ).parseCompilationUnit(tokens);
-    }
-    return _unit!;
+    return _unit ??= parseString(content: contents).unit;
   }
 
   Token findToken(String lexeme) {
@@ -1005,15 +981,10 @@
     var body = method.body as BlockFunctionBody;
     Statement statement = body.block.statements[0];
 
-    GatheringErrorListener listener = GatheringErrorListener(checkRanges: true);
-    var source = StringSource('missing', 'PreviousTokenTest_missing.dart');
-    var scanner = Scanner.fasta(source, listener)
-      ..configureFeatures(
-        featureSetForOverriding: featureSet,
-        featureSet: featureSet,
-      );
-    Token missing = scanner.tokenize();
-
+    var missing = parseString(
+      content: 'missing',
+      throwIfDiagnostics: false,
+    ).unit.beginToken;
     expect(statement.findPrevious(missing), null);
   }
 
diff --git a/pkg/analyzer/test/generated/class_member_parser_test.dart b/pkg/analyzer/test/generated/class_member_parser_test.dart
index 25467ad..515d419 100644
--- a/pkg/analyzer/test/generated/class_member_parser_test.dart
+++ b/pkg/analyzer/test/generated/class_member_parser_test.dart
@@ -2,7 +2,6 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -22,9 +21,6 @@
 @reflectiveTest
 class ClassMemberParserTest extends FastaParserTestCase
     implements AbstractParserViaProxyTestCase {
-  final tripleShift = FeatureSet.forTesting(
-      sdkVersion: '2.0.0', additionalFeatures: [Feature.triple_shift]);
-
   void test_parse_member_called_late() {
     var unit = parseCompilationUnit(
         'class C { void late() { new C().late(); } }',
@@ -1032,8 +1028,8 @@
 
   void test_parseClassMember_operator_gtgtgt() {
     var unit = parseCompilationUnit(
-        'class C { bool operator >>>(other) => false; }',
-        featureSet: tripleShift);
+      'class C { bool operator >>>(other) => false; }',
+    );
     var declaration = unit.declarations[0] as ClassDeclaration;
     var method = declaration.members[0] as MethodDeclaration;
 
@@ -1051,8 +1047,8 @@
 
   void test_parseClassMember_operator_gtgtgteq() {
     var unit = parseCompilationUnit(
-        'class C { foo(int value) { x >>>= value; } }',
-        featureSet: tripleShift);
+      'class C { foo(int value) { x >>>= value; } }',
+    );
     var declaration = unit.declarations[0] as ClassDeclaration;
     var method = declaration.members[0] as MethodDeclaration;
     var blockFunctionBody = method.body as BlockFunctionBody;
diff --git a/pkg/analyzer/test/generated/collection_literal_parser_test.dart b/pkg/analyzer/test/generated/collection_literal_parser_test.dart
index b5b211a..7e39201 100644
--- a/pkg/analyzer/test/generated/collection_literal_parser_test.dart
+++ b/pkg/analyzer/test/generated/collection_literal_parser_test.dart
@@ -2,7 +2,6 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:test/test.dart';
@@ -24,17 +23,13 @@
       List<ExpectedError>? errors,
       int? expectedEndOffset,
       bool inAsync = false}) {
-    return parseExpression(source,
-        codes: codes,
-        errors: errors,
-        expectedEndOffset: expectedEndOffset,
-        inAsync: inAsync,
-        featureSet: FeatureSet.forTesting(
-            sdkVersion: '2.0.0',
-            additionalFeatures: [
-              Feature.spread_collections,
-              Feature.control_flow_collections
-            ]));
+    return parseExpression(
+      source,
+      codes: codes,
+      errors: errors,
+      expectedEndOffset: expectedEndOffset,
+      inAsync: inAsync,
+    );
   }
 
   void test_listLiteral_for() {
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index 4920947..4a17b0e 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -20,6 +20,19 @@
 
 @reflectiveTest
 class ConstantEvaluatorTest extends PubPackageResolutionTest {
+  void assertTypeArguments(DartObject value, List<String>? typeArgumentNames) {
+    var typeArguments = (value as DartObjectImpl).typeArguments;
+    if (typeArguments == null) {
+      expect(typeArguments, typeArgumentNames);
+      return;
+    }
+    expect(
+      typeArguments.map(
+          (arg) => arg.toTypeValue()!.getDisplayString(withNullability: false)),
+      equals(typeArgumentNames),
+    );
+  }
+
   test_bitAnd_int_int() async {
     await _assertValueInt(74 & 42, "74 & 42");
   }
@@ -213,6 +226,100 @@
     await _assertValueBool(false, "'a' == 'b'");
   }
 
+  test_functionReference_explicitTypeArgs_badBound() async {
+    var result = await _getExpressionValue("foo<String>", context: '''
+void foo<T extends num>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'void Function(String)');
+    assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
+    assertTypeArguments(value, ['String']);
+  }
+
+  test_functionReference_explicitTypeArgs_differentElements() async {
+    var result = await _getExpressionValue("(b ? foo : bar)<int>", context: '''
+const b = true;
+void foo<T>(String a, T b) {}
+void bar<T>(T a, String b) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'void Function(String, int)');
+    assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
+    assertTypeArguments(value, ['int']);
+  }
+
+  test_functionReference_explicitTypeArgs_identifier() async {
+    // TODO(srawlins): Add test where the type argument is a type variable.
+    var result = await _getExpressionValue("foo<int>", context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    var value = result.value!;
+    assertType(value.type, 'void Function(int)');
+    assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
+    assertTypeArguments(value, ['int']);
+  }
+
+  test_functionReference_explicitTypeArgs_nonIdentifier() async {
+    var result = await _getExpressionValue("(b ? foo : bar)<int>", context: '''
+const b = true;
+void foo<T>(T a) {}
+void bar<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    var value = result.value!;
+    assertType(value.type, 'void Function(int)');
+    assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
+    assertTypeArguments(value, ['int']);
+  }
+
+  test_functionReference_explicitTypeArgs_notAType() async {
+    var result = await _getExpressionValue("foo<true>", context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isFalse);
+  }
+
+  test_functionReference_explicitTypeArgs_tooFew() async {
+    var result = await _getExpressionValue("foo<int>", context: '''
+void foo<T, U>(T a) {}
+''');
+    expect(result.isValid, isFalse);
+  }
+
+  test_functionReference_explicitTypeArgs_tooMany() async {
+    var result = await _getExpressionValue("foo<int, int>", context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isFalse);
+  }
+
+  test_functionReference_uninstantiated_identifier() async {
+    var result = await _getExpressionValue("foo", context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'void Function<T>(T)');
+    assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
+    assertTypeArguments(value, null);
+  }
+
+  test_functionReference_uninstantiated_nonIdentifier() async {
+    var result = await _getExpressionValue("b ? foo : bar", context: '''
+const b = true;
+void foo<T>(T a) {}
+void bar<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'void Function<T>(T)');
+    assertElement(value.toFunctionValue(), findElement.topFunction('foo'));
+    assertTypeArguments(value, null);
+  }
+
   test_greaterThan_int_int() async {
     await _assertValueBool(false, "2 > 3");
   }
@@ -221,6 +328,51 @@
     await _assertValueBool(false, "2 >= 3");
   }
 
+  test_identical_functionReference_explicitTypeArgs_differentElements() async {
+    var result =
+        await _getExpressionValue("identical(foo<int>, bar<int>)", context: '''
+void foo<T>(T a) {}
+void bar<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'bool');
+    expect(value.toBoolValue(), false);
+  }
+
+  test_identical_functionReference_explicitTypeArgs_differentTypeArgs() async {
+    var result = await _getExpressionValue("identical(foo<int>, foo<String>)",
+        context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'bool');
+    expect(value.toBoolValue(), false);
+  }
+
+  test_identical_functionReference_explicitTypeArgs_sameElement() async {
+    var result =
+        await _getExpressionValue("identical(foo<int>, foo<int>)", context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'bool');
+    expect(value.toBoolValue(), true);
+  }
+
+  test_identical_functionReference_onlyOneHasTypeArgs() async {
+    var result =
+        await _getExpressionValue("identical(foo<int>, foo)", context: '''
+void foo<T>(T a) {}
+''');
+    expect(result.isValid, isTrue);
+    DartObject value = result.value!;
+    assertType(value.type, 'bool');
+    expect(value.toBoolValue(), false);
+  }
+
   @failingTest
   test_identifier_class() async {
     var result = await _getExpressionValue("?");
@@ -294,6 +446,16 @@
     expect(result.isValid, isTrue);
   }
 
+  test_literal_list_explicitType() async {
+    var result = await _getExpressionValue("const <String>['a', 'b', 'c']");
+    expect(result.isValid, isTrue);
+  }
+
+  test_literal_list_explicitType_functionType() async {
+    var result = await _getExpressionValue("const <void Function()>[]");
+    expect(result.isValid, isTrue);
+  }
+
   test_literal_list_forElement() async {
     var result = await _getExpressionValue('''
 const [for (var i = 0; i < 4; i++) i]
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 1d3df59..074ada9 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -716,15 +716,14 @@
     Source source = FileSource(getFile("/test.dart"));
     CompilationUnitElementImpl unit = CompilationUnitElementImpl();
     unit.librarySource = unit.source = source;
-    _definingLibrary =
-        ElementFactory.library(context, "test", isNonNullableByDefault: false);
+    _definingLibrary = ElementFactory.library(context, "test");
     _definingLibrary.definingCompilationUnit = unit;
 
     _definingLibrary.typeProvider = context.typeProviderLegacy;
     _definingLibrary.typeSystem = context.typeSystemLegacy;
     var inheritance = InheritanceManager3();
 
-    var featureSet = FeatureSet.forTesting();
+    var featureSet = FeatureSet.latestLanguageVersion();
     _visitor = ResolverVisitor(
         inheritance, _definingLibrary, source, _typeProvider, _listener,
         featureSet: featureSet,
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index c201074..8c01ffe 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -7,7 +7,6 @@
 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/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -374,12 +373,7 @@
       uriStr,
       -1,
       0,
-      FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: ExperimentStatus.testingSdkLanguageVersion,
-        flags: typeSystem.isNonNullableByDefault
-            ? [EnableString.non_nullable]
-            : [],
-      ),
+      FeatureSet.latestLanguageVersion(),
     );
     library.typeSystem = typeSystem;
     library.typeProvider = typeSystem.typeProvider;
diff --git a/pkg/analyzer/test/generated/generic_metadata_parser_test.dart b/pkg/analyzer/test/generated/generic_metadata_parser_test.dart
index 05e1c6d..c4627d1 100644
--- a/pkg/analyzer/test/generated/generic_metadata_parser_test.dart
+++ b/pkg/analyzer/test/generated/generic_metadata_parser_test.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -26,9 +27,14 @@
       {List<ExpectedError>? errors, required ExpectedError? disabledError}) {
     var combinedErrors =
         disabledError == null ? errors : [disabledError, ...?errors];
-    return parseCompilationUnit(content,
-        errors: combinedErrors,
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.12'));
+    return parseCompilationUnit(
+      content,
+      errors: combinedErrors,
+      featureSet: FeatureSet.fromEnableFlags2(
+        sdkLanguageVersion: Version.parse('2.12.0'),
+        flags: [],
+      ),
+    );
   }
 }
 
@@ -39,11 +45,7 @@
   CompilationUnit _parseCompilationUnit(String content,
           {List<ExpectedError>? errors,
           required ExpectedError? disabledError}) =>
-      parseCompilationUnit(content,
-          errors: errors,
-          featureSet: FeatureSet.forTesting(
-              sdkVersion: '2.12',
-              additionalFeatures: [Feature.generic_metadata]));
+      parseCompilationUnit(content, errors: errors);
 }
 
 mixin GenericMetadataParserTest on FastaParserTestCase {
diff --git a/pkg/analyzer/test/generated/parser_test_base.dart b/pkg/analyzer/test/generated/parser_test_base.dart
index 956e4ae..aa56d56 100644
--- a/pkg/analyzer/test/generated/parser_test_base.dart
+++ b/pkg/analyzer/test/generated/parser_test_base.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart' show CompilationUnitImpl;
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
@@ -220,8 +221,10 @@
     implements AbstractParserTestCase {
   static final List<ErrorCode> NO_ERROR_COMPARISON = <ErrorCode>[];
 
-  final constructorTearoffs = FeatureSet.forTesting(
-      sdkVersion: '2.14.0', additionalFeatures: [Feature.constructor_tearoffs]);
+  final constructorTearoffs = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: ExperimentStatus.currentVersion,
+    flags: [EnableString.constructor_tearoffs],
+  );
 
   final controlFlow = FeatureSet.latestLanguageVersion();
 
@@ -289,7 +292,7 @@
   @override
   void createParser(String content,
       {int? expectedEndOffset, FeatureSet? featureSet}) {
-    featureSet ??= FeatureSet.forTesting();
+    featureSet ??= FeatureSet.latestLanguageVersion();
     var result = scanString(content,
         configuration: featureSet.isEnabled(Feature.non_nullable)
             ? ScannerConfiguration.nonNullable
@@ -407,8 +410,8 @@
 
   CompilationUnitImpl parseCompilationUnit2(
       String content, GatheringErrorListener listener,
-      {LanguageVersionToken? languageVersion, FeatureSet? featureSet}) {
-    featureSet ??= FeatureSet.forTesting();
+      {FeatureSet? featureSet}) {
+    featureSet ??= FeatureSet.latestLanguageVersion();
     var source = StringSource(content, 'parser_test_StringSource.dart');
 
     // Adjust the feature set based on language version comment.
@@ -1166,7 +1169,7 @@
     analyzer.Parser parser = analyzer.Parser(
       source,
       listener,
-      featureSet: FeatureSet.forTesting(),
+      featureSet: FeatureSet.latestLanguageVersion(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
     CompilationUnit unit = parser.parseCompilationUnit(result.tokens);
@@ -1193,7 +1196,7 @@
     analyzer.Parser parser = analyzer.Parser(
       source,
       listener,
-      featureSet: FeatureSet.forTesting(),
+      featureSet: FeatureSet.latestLanguageVersion(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
     var unit = parser.parseCompilationUnit(result.tokens);
@@ -1471,7 +1474,7 @@
     analyzer.Parser parser = analyzer.Parser(
       source,
       listener,
-      featureSet: FeatureSet.forTesting(),
+      featureSet: FeatureSet.latestLanguageVersion(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
     Statement statement = parser.parseStatement(result.tokens);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index ed20e1a..08cf6ac 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -82,7 +82,7 @@
 
 @reflectiveTest
 class LineInfoTest {
-  final featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
+  final featureSet = FeatureSet.latestLanguageVersion();
 
   void test_lineInfo_multilineComment() {
     String source = "/*\r\n *\r\n */";
@@ -208,8 +208,8 @@
     expect(defaultFeatureSet.isEnabled(Feature.extension_methods), isTrue);
 
     scanner.configureFeatures(
-      featureSetForOverriding: FeatureSet.forTesting(),
-      featureSet: FeatureSet.forTesting(),
+      featureSetForOverriding: FeatureSet.latestLanguageVersion(),
+      featureSet: FeatureSet.latestLanguageVersion(),
     );
     scanner.tokenize();
 
@@ -221,7 +221,7 @@
     var scanner = _createScanner(r'''
 // @dart = 99999999999999999999999999999999.0
 ''');
-    var featureSet = FeatureSet.forTesting();
+    var featureSet = FeatureSet.latestLanguageVersion();
     scanner.configureFeatures(
       featureSetForOverriding: featureSet,
       featureSet: featureSet,
@@ -234,7 +234,7 @@
     var scanner = _createScanner(r'''
 // @dart = 2.99999999999999999999999999999999
 ''');
-    var featureSet = FeatureSet.forTesting();
+    var featureSet = FeatureSet.latestLanguageVersion();
     scanner.configureFeatures(
       featureSetForOverriding: featureSet,
       featureSet: featureSet,
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 0e2c9d5..affcebc 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -503,7 +503,7 @@
         CompilationUnitElementImpl();
     definingCompilationUnit.librarySource =
         definingCompilationUnit.source = source;
-    var featureSet = FeatureSet.forTesting();
+    var featureSet = FeatureSet.latestLanguageVersion();
 
     _definingLibrary = LibraryElementImpl(
         context, _AnalysisSessionMock(), 'name', -1, 0, featureSet);
diff --git a/pkg/analyzer/test/generated/test_analysis_context.dart b/pkg/analyzer/test/generated/test_analysis_context.dart
index 473c34a..6702b63 100644
--- a/pkg/analyzer/test/generated/test_analysis_context.dart
+++ b/pkg/analyzer/test/generated/test_analysis_context.dart
@@ -28,7 +28,7 @@
 
   TestAnalysisContext({FeatureSet? featureSet}) {
     _analysisOptions = AnalysisOptionsImpl()
-      ..contextFeatures = featureSet ?? FeatureSet.forTesting();
+      ..contextFeatures = featureSet ?? FeatureSet.latestLanguageVersion();
 
     var sdkElements = MockSdkElements(this, _analysisSession);
 
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 492236c..b0d0ce9 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -24,7 +24,7 @@
   });
 }
 
-abstract class AbstractTypeSystemNullSafetyTest with ElementsTypesMixin {
+abstract class AbstractTypeSystemTest with ElementsTypesMixin {
   late TestAnalysisContext analysisContext;
 
   @override
@@ -36,9 +36,7 @@
   late TypeSystemImpl typeSystem;
 
   FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
+    return FeatureSet.latestLanguageVersion();
   }
 
   void setUp() {
@@ -57,7 +55,7 @@
   }
 }
 
-abstract class AbstractTypeSystemTest with ElementsTypesMixin {
+abstract class AbstractTypeSystemWithoutNullSafetyTest with ElementsTypesMixin {
   late TestAnalysisContext analysisContext;
 
   @override
@@ -69,7 +67,7 @@
   late TypeSystemImpl typeSystem;
 
   FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting();
+    return FeatureSet.latestLanguageVersion();
   }
 
   void setUp() {
@@ -89,7 +87,7 @@
 }
 
 @reflectiveTest
-class AssignabilityTest extends AbstractTypeSystemTest {
+class AssignabilityTest extends AbstractTypeSystemWithoutNullSafetyTest {
   void test_isAssignableTo_bottom_isBottom() {
     var A = class_(name: 'A');
     List<DartType> interassignable = <DartType>[
@@ -437,14 +435,7 @@
 }
 
 @reflectiveTest
-class TryPromoteToTest extends AbstractTypeSystemTest {
-  @override
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
-  }
-
+class TryPromoteToTest extends AbstractTypeSystemWithoutNullSafetyTest {
   void notPromotes(DartType from, DartType to) {
     var result = typeSystem.tryPromoteToType(to, from);
     expect(result, isNull);
diff --git a/pkg/analyzer/test/generated/variance_parser_test.dart b/pkg/analyzer/test/generated/variance_parser_test.dart
index 1208056..37c8af3 100644
--- a/pkg/analyzer/test/generated/variance_parser_test.dart
+++ b/pkg/analyzer/test/generated/variance_parser_test.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:test/test.dart';
@@ -21,19 +22,24 @@
 
 @reflectiveTest
 class VarianceParserTest extends FastaParserTestCase {
+  final FeatureSet _disabledFeatureSet = FeatureSet.latestLanguageVersion();
+
+  final FeatureSet _enabledFeatureSet = FeatureSet.fromEnableFlags2(
+    sdkLanguageVersion: ExperimentStatus.currentVersion,
+    flags: [EnableString.variance],
+  );
+
   @override
   CompilationUnitImpl parseCompilationUnit(String content,
       {List<ErrorCode>? codes,
       List<ExpectedError>? errors,
       FeatureSet? featureSet}) {
-    return super.parseCompilationUnit(content,
-        codes: codes,
-        errors: errors,
-        featureSet: featureSet ??
-            FeatureSet.forTesting(
-              sdkVersion: '2.5.0',
-              additionalFeatures: [Feature.variance],
-            ));
+    return super.parseCompilationUnit(
+      content,
+      codes: codes,
+      errors: errors,
+      featureSet: featureSet ?? _enabledFeatureSet,
+    );
   }
 
   void test_class_disabled_multiple() {
@@ -43,7 +49,7 @@
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_class_disabled_single() {
@@ -51,7 +57,7 @@
         errors: [
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_class_enabled_multiple() {
@@ -124,7 +130,7 @@
               ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 7, 2),
           expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_function_enabled() {
@@ -139,7 +145,7 @@
         errors: [
           expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_list_enabled() {
@@ -154,7 +160,7 @@
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_mixin_disabled_single() {
@@ -162,7 +168,7 @@
         errors: [
           expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_mixin_enabled_single() {
@@ -181,7 +187,7 @@
         errors: [
           expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
         ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+        featureSet: _disabledFeatureSet);
   }
 
   void test_typedef_enabled() {
diff --git a/pkg/analyzer/test/id_tests/nullability_test.dart b/pkg/analyzer/test/id_tests/nullability_test.dart
index c74f028..72fd2ef 100644
--- a/pkg/analyzer/test/id_tests/nullability_test.dart
+++ b/pkg/analyzer/test/id_tests/nullability_test.dart
@@ -35,11 +35,8 @@
 
   /// Resolve the given [code] and track nullability in the unit.
   Future<void> trackCode(String code) async {
-    TestResult<String> testResult = await checkTests(
-        code,
-        const _NullabilityDataComputer(),
-        FeatureSet.forTesting(
-            sdkVersion: '2.2.2', additionalFeatures: [Feature.non_nullable]));
+    TestResult<String> testResult = await checkTests(code,
+        const _NullabilityDataComputer(), FeatureSet.latestLanguageVersion());
     if (testResult.hasFailures) {
       fail('Failure(s)');
     }
diff --git a/pkg/analyzer/test/id_tests/reachability_test.dart b/pkg/analyzer/test/id_tests/reachability_test.dart
index 7b4c957..8714082 100644
--- a/pkg/analyzer/test/id_tests/reachability_test.dart
+++ b/pkg/analyzer/test/id_tests/reachability_test.dart
@@ -31,11 +31,8 @@
 
   /// Resolve the given [code] and track nullability in the unit.
   Future<void> trackCode(String code) async {
-    TestResult<Set<_ReachabilityAssertion>> testResult = await checkTests(
-        code,
-        const _ReachabilityDataComputer(),
-        FeatureSet.forTesting(
-            sdkVersion: '2.2.2', additionalFeatures: [Feature.non_nullable]));
+    TestResult<Set<_ReachabilityAssertion>> testResult = await checkTests(code,
+        const _ReachabilityDataComputer(), FeatureSet.latestLanguageVersion());
     if (testResult.hasFailures) {
       fail('Failure(s)');
     }
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 1bb79b1..536922f 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/status.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
@@ -40,8 +39,6 @@
   late final String testFile;
   late final String testCode;
 
-  List<String> enabledExperiments = [];
-
   void addTestFile(String content, {bool priority = false}) {
     testCode = content;
     newFile(testFile, content: content);
@@ -98,10 +95,7 @@
 
   AnalysisOptionsImpl createAnalysisOptions() => AnalysisOptionsImpl()
     ..useFastaParser = true
-    ..contextFeatures = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: ExperimentStatus.testingSdkLanguageVersion,
-      flags: enabledExperiments,
-    );
+    ..contextFeatures = FeatureSet.latestLanguageVersion();
 
   int findOffset(String search) {
     int offset = testCode.indexOf(search);
diff --git a/pkg/analyzer/test/src/dart/analysis/experiments_test.dart b/pkg/analyzer/test/src/dart/analysis/experiments_test.dart
index 573bc1b..f808c64 100644
--- a/pkg/analyzer/test/src/dart/analysis/experiments_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/experiments_test.dart
@@ -18,10 +18,10 @@
 class ExperimentsTest {
   var knownFeatures = <String, ExperimentalFeature>{};
 
-  void assertLatestSdkLanguageVersion(ExperimentStatus status) {
+  void assertCurrentSdkLanguageVersion(ExperimentStatus status) {
     expect(
       getSdkLanguageVersion(status),
-      ExperimentStatus.latestSdkLanguageVersion,
+      ExperimentStatus.currentVersion,
     );
   }
 
@@ -126,10 +126,10 @@
       releaseVersion: null,
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['no-a', 'a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -145,10 +145,10 @@
       releaseVersion: null,
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['a', 'no-a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -163,10 +163,10 @@
       releaseVersion: null,
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['no-a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -181,10 +181,10 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['no-a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -208,10 +208,10 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: [],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false, true]);
   }
 
@@ -226,10 +226,10 @@
       releaseVersion: null,
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -244,10 +244,10 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -263,10 +263,10 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['no-a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -282,10 +282,10 @@
       releaseVersion: null,
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -301,10 +301,10 @@
       releaseVersion: null,
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['no-a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -320,20 +320,20 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
   test_fromStrings2_flags_unrecognized() {
     // Unrecognized flags are ignored.
     var status = fromStrings2(
-      sdkLanguageVersion: ExperimentStatus.latestSdkLanguageVersion,
+      sdkLanguageVersion: ExperimentStatus.currentVersion,
       flags: ['a'],
     );
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), <Object>[]);
   }
 
@@ -485,7 +485,7 @@
       releaseVersion: null,
     );
     var status = fromStrings(['no-a', 'a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -501,7 +501,7 @@
       releaseVersion: null,
     );
     var status = fromStrings(['a', 'no-a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -525,7 +525,7 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings([]);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false, true]);
   }
 
@@ -540,7 +540,7 @@
       releaseVersion: null,
     );
     var status = fromStrings(['no-a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -555,7 +555,7 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings(['no-a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -570,7 +570,7 @@
       releaseVersion: null,
     );
     var status = fromStrings(['a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -585,7 +585,7 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings(['a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -601,7 +601,7 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings(['no-a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
@@ -617,7 +617,7 @@
       releaseVersion: null,
     );
     var status = fromStrings(['a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -633,7 +633,7 @@
       releaseVersion: null,
     );
     var status = fromStrings(['no-a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [false]);
   }
 
@@ -649,14 +649,14 @@
       releaseVersion: Version.parse('1.0.0'),
     );
     var status = fromStrings(['a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), [true]);
   }
 
   test_fromStrings_unrecognized_flag() {
     // Unrecognized flags are ignored.
     var status = fromStrings(['a']);
-    assertLatestSdkLanguageVersion(status);
+    assertCurrentSdkLanguageVersion(status);
     expect(getFlags(status), <Object>[]);
   }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
index 5d2201c..7bd38c2 100644
--- a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -2,9 +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 file.
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/dart/analysis/unlinked_api_signature.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -13,7 +11,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UnitApiSignatureTest);
-    defineReflectiveTests(UnitApiSignatureWithNullSafetyTest);
   });
 }
 
@@ -344,6 +341,30 @@
 ''');
   }
 
+  test_class_field_late_add() {
+    assertNotSameSignature(r'''
+class C {
+  int a;
+}
+''', r'''
+class C {
+  late int a;
+}
+''');
+  }
+
+  test_class_field_late_remove() {
+    assertNotSameSignature(r'''
+class C {
+  late int a;
+}
+''', r'''
+class C {
+  int a;
+}
+''');
+  }
+
   test_class_field_static_add() {
     assertNotSameSignature(r'''
 class C {
@@ -1224,6 +1245,22 @@
 ''');
   }
 
+  test_topLevelVariable_late_add() {
+    assertNotSameSignature(r'''
+int a;
+''', r'''
+late int a;
+''');
+  }
+
+  test_topLevelVariable_late_remove() {
+    assertNotSameSignature(r'''
+late int a;
+''', r'''
+int a;
+''');
+  }
+
   test_topLevelVariable_withoutType() {
     assertNotSameSignature(r'''
 var a = 1;
@@ -1288,51 +1325,3 @@
 ''');
   }
 }
-
-@reflectiveTest
-class UnitApiSignatureWithNullSafetyTest extends UnitApiSignatureTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = FeatureSet.forTesting(
-        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
-
-  test_class_field_late_add() {
-    assertNotSameSignature(r'''
-class C {
-  int a;
-}
-''', r'''
-class C {
-  late int a;
-}
-''');
-  }
-
-  test_class_field_late_remove() {
-    assertNotSameSignature(r'''
-class C {
-  late int a;
-}
-''', r'''
-class C {
-  int a;
-}
-''');
-  }
-
-  test_topLevelVariable_late_add() {
-    assertNotSameSignature(r'''
-int a;
-''', r'''
-late int a;
-''');
-  }
-
-  test_topLevelVariable_late_remove() {
-    assertNotSameSignature(r'''
-late int a;
-''', r'''
-int a;
-''');
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 1db519f..ba67935 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -920,6 +920,35 @@
     expect(result.toDoubleValue(), 3.0);
   }
 
+  test_visitIsExpression_is_functionType_badTypes() async {
+    await resolveTestCode('''
+void foo(int a) {}
+const c = foo is void Function(String);
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
+  test_visitIsExpression_is_functionType_correctTypes() async {
+    await resolveTestCode('''
+void foo(int a) {}
+const c = foo is void Function(int);
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_is_functionType_nonFunction() async {
+    await resolveTestCode('''
+const c = false is void Function();
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
   test_visitIsExpression_is_instanceOfSameClass() async {
     await resolveTestCode('''
 const a = const A();
diff --git a/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart b/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart
index bc0be60..8d2e5cd 100644
--- a/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/has_type_parameter_reference_test.dart
@@ -16,7 +16,7 @@
 }
 
 @reflectiveTest
-class HasTypeParameterReferenceTest extends AbstractTypeSystemNullSafetyTest {
+class HasTypeParameterReferenceTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _checkFalse(dynamicNone);
   }
diff --git a/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart b/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
index 2dd1c49..cf35b13 100644
--- a/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
+++ b/pkg/analyzer/test/src/dart/element/class_hierarchy_test.dart
@@ -21,7 +21,7 @@
 }
 
 @reflectiveTest
-class ClassHierarchyLegacyTest extends AbstractTypeSystemTest
+class ClassHierarchyLegacyTest extends AbstractTypeSystemWithoutNullSafetyTest
     with _AbstractClassHierarchyMixin {
   @override
   void setUp() {
@@ -46,7 +46,7 @@
 }
 
 @reflectiveTest
-class ClassHierarchyNullSafetyTest extends AbstractTypeSystemNullSafetyTest
+class ClassHierarchyNullSafetyTest extends AbstractTypeSystemTest
     with _AbstractClassHierarchyMixin {
   @override
   void setUp() {
diff --git a/pkg/analyzer/test/src/dart/element/factor_type_test.dart b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
index 240c5bf..fee6ba8 100644
--- a/pkg/analyzer/test/src/dart/element/factor_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/factor_type_test.dart
@@ -27,12 +27,6 @@
 
   late final TypeSystemImpl typeSystem;
 
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
-  }
-
   @override
   DartType get voidType => typeProvider.voidType;
 
@@ -49,7 +43,7 @@
 
   void setUp() {
     var analysisContext = TestAnalysisContext(
-      featureSet: testFeatureSet,
+      featureSet: FeatureSet.latestLanguageVersion(),
     );
     typeProvider = analysisContext.typeProviderNonNullableByDefault;
     typeSystem = analysisContext.typeSystemNonNullableByDefault;
diff --git a/pkg/analyzer/test/src/dart/element/flatten_type_test.dart b/pkg/analyzer/test/src/dart/element/flatten_type_test.dart
index de300b9..fa4fbd57 100644
--- a/pkg/analyzer/test/src/dart/element/flatten_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/flatten_type_test.dart
@@ -16,7 +16,7 @@
 }
 
 @reflectiveTest
-class FlattenTypeTest extends AbstractTypeSystemNullSafetyTest {
+class FlattenTypeTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _check(dynamicNone, 'dynamic');
   }
diff --git a/pkg/analyzer/test/src/dart/element/future_or_base_test.dart b/pkg/analyzer/test/src/dart/element/future_or_base_test.dart
index c70b702..a777618 100644
--- a/pkg/analyzer/test/src/dart/element/future_or_base_test.dart
+++ b/pkg/analyzer/test/src/dart/element/future_or_base_test.dart
@@ -15,7 +15,7 @@
 }
 
 @reflectiveTest
-class FutureOrBaseTest extends AbstractTypeSystemNullSafetyTest {
+class FutureOrBaseTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _check(dynamicNone, 'dynamic');
   }
diff --git a/pkg/analyzer/test/src/dart/element/future_value_type_test.dart b/pkg/analyzer/test/src/dart/element/future_value_type_test.dart
index 6c789e7..fc9fe60 100644
--- a/pkg/analyzer/test/src/dart/element/future_value_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/future_value_type_test.dart
@@ -15,7 +15,7 @@
 }
 
 @reflectiveTest
-class FutureValueTypeTest extends AbstractTypeSystemNullSafetyTest {
+class FutureValueTypeTest extends AbstractTypeSystemTest {
   /// futureValueType(`dynamic`) = `dynamic`.
   test_dynamic() {
     _check(dynamicNone, 'dynamic');
diff --git a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
index 7933c6f..853eb50 100644
--- a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -24,7 +24,7 @@
 }
 
 @reflectiveTest
-class GenericFunctionInferenceTest extends AbstractTypeSystemNullSafetyTest {
+class GenericFunctionInferenceTest extends AbstractTypeSystemTest {
   void test_boundedByAnotherTypeParameter() {
     // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
     var tFrom = typeParameter('TFrom');
diff --git a/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart b/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
index 8c1a570..9c1f2df 100644
--- a/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
@@ -17,7 +17,8 @@
 }
 
 @reflectiveTest
-class GreatestClosureLegacyTest extends AbstractTypeSystemTest {
+class GreatestClosureLegacyTest
+    extends AbstractTypeSystemWithoutNullSafetyTest {
   late final TypeParameterElement T;
   late final TypeParameterType T_none;
   late final TypeParameterType T_question;
@@ -141,7 +142,7 @@
 }
 
 @reflectiveTest
-class GreatestClosureNullSafetyTest extends AbstractTypeSystemNullSafetyTest {
+class GreatestClosureNullSafetyTest extends AbstractTypeSystemTest {
   late final TypeParameterElement T;
   late final TypeParameterType T_none;
   late final TypeParameterType T_question;
diff --git a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
index c5e85ce..83fc399 100644
--- a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
@@ -21,7 +21,7 @@
 }
 
 @reflectiveTest
-class PathToObjectTest extends AbstractTypeSystemTest {
+class PathToObjectTest extends AbstractTypeSystemWithoutNullSafetyTest {
   @override
   final TestTypeProvider typeProvider = TestTypeProvider();
 
@@ -351,7 +351,7 @@
 }
 
 @reflectiveTest
-class SuperinterfaceSetTest extends AbstractTypeSystemTest {
+class SuperinterfaceSetTest extends AbstractTypeSystemWithoutNullSafetyTest {
   @override
   final TestTypeProvider typeProvider = TestTypeProvider();
 
diff --git a/pkg/analyzer/test/src/dart/element/normalize_type_test.dart b/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
index f99b5a0..bb73cc4c 100644
--- a/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
@@ -2,19 +2,15 @@
 // 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/analysis/features.dart';
 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_provider.dart';
 import 'package:analyzer/dart/element/type_visitor.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/elements_types_mixin.dart';
-import '../../../generated/test_analysis_context.dart';
+import '../../../generated/type_system_test.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -23,26 +19,7 @@
 }
 
 @reflectiveTest
-class NormalizeTypeTest with ElementsTypesMixin {
-  @override
-  late final TypeProvider typeProvider;
-
-  late final TypeSystemImpl typeSystem;
-
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
-  }
-
-  void setUp() {
-    var analysisContext = TestAnalysisContext(
-      featureSet: testFeatureSet,
-    );
-    typeProvider = analysisContext.typeProviderNonNullableByDefault;
-    typeSystem = analysisContext.typeSystemNonNullableByDefault;
-  }
-
+class NormalizeTypeTest extends AbstractTypeSystemTest {
   test_functionType_parameter() {
     _check(
       functionTypeNone(
diff --git a/pkg/analyzer/test/src/dart/element/nullability_eliminator_test.dart b/pkg/analyzer/test/src/dart/element/nullability_eliminator_test.dart
index ff5c8f9..4471b73 100644
--- a/pkg/analyzer/test/src/dart/element/nullability_eliminator_test.dart
+++ b/pkg/analyzer/test/src/dart/element/nullability_eliminator_test.dart
@@ -18,7 +18,7 @@
 }
 
 @reflectiveTest
-class NullabilityEliminatorTest extends AbstractTypeSystemNullSafetyTest {
+class NullabilityEliminatorTest extends AbstractTypeSystemTest {
   test_dynamicType() {
     _verifySame(typeProvider.dynamicType);
   }
diff --git a/pkg/analyzer/test/src/dart/element/nullable_test.dart b/pkg/analyzer/test/src/dart/element/nullable_test.dart
index 1bfb595..92f4950 100644
--- a/pkg/analyzer/test/src/dart/element/nullable_test.dart
+++ b/pkg/analyzer/test/src/dart/element/nullable_test.dart
@@ -23,7 +23,7 @@
 }
 
 @reflectiveTest
-class IsNonNullableTest extends AbstractTypeSystemNullSafetyTest {
+class IsNonNullableTest extends AbstractTypeSystemTest {
   void isNonNullable(DartType type) {
     expect(typeSystem.isNonNullable(type), isTrue);
   }
@@ -188,7 +188,7 @@
 }
 
 @reflectiveTest
-class IsNullableTest extends AbstractTypeSystemNullSafetyTest {
+class IsNullableTest extends AbstractTypeSystemTest {
   void isNotNullable(DartType type) {
     expect(typeSystem.isNullable(type), isFalse);
   }
@@ -353,7 +353,7 @@
 }
 
 @reflectiveTest
-class IsPotentiallyNonNullableTest extends AbstractTypeSystemNullSafetyTest {
+class IsPotentiallyNonNullableTest extends AbstractTypeSystemTest {
   void isNotPotentiallyNonNullable(DartType type) {
     expect(typeSystem.isPotentiallyNonNullable(type), isFalse);
   }
@@ -400,7 +400,7 @@
 }
 
 @reflectiveTest
-class IsPotentiallyNullableTest extends AbstractTypeSystemNullSafetyTest {
+class IsPotentiallyNullableTest extends AbstractTypeSystemTest {
   void isNotPotentiallyNullable(DartType type) {
     expect(typeSystem.isPotentiallyNullable(type), isFalse);
   }
@@ -447,7 +447,7 @@
 }
 
 @reflectiveTest
-class IsStrictlyNonNullableTest extends AbstractTypeSystemNullSafetyTest {
+class IsStrictlyNonNullableTest extends AbstractTypeSystemTest {
   void isNotStrictlyNonNullable(DartType type) {
     expect(typeSystem.isStrictlyNonNullable(type), isFalse);
   }
@@ -594,7 +594,7 @@
 }
 
 @reflectiveTest
-class PromoteToNonNullTest extends AbstractTypeSystemNullSafetyTest {
+class PromoteToNonNullTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _check(dynamicType, dynamicType);
   }
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
index 54a3fd6..ffdc9cc 100644
--- a/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
+++ b/pkg/analyzer/test/src/dart/element/replace_top_bottom_test.dart
@@ -18,7 +18,8 @@
 }
 
 @reflectiveTest
-class ReplaceTopBottomLegacyTest extends AbstractTypeSystemTest {
+class ReplaceTopBottomLegacyTest
+    extends AbstractTypeSystemWithoutNullSafetyTest {
   test_contravariant_bottom() {
     // Not contravariant.
     _check(nullStar, 'Null*');
@@ -77,7 +78,7 @@
 }
 
 @reflectiveTest
-class ReplaceTopBottomNullSafetyTest extends AbstractTypeSystemNullSafetyTest {
+class ReplaceTopBottomNullSafetyTest extends AbstractTypeSystemTest {
   test_contravariant_bottom() {
     // Not contravariant.
     _check(neverNone, 'Never');
diff --git a/pkg/analyzer/test/src/dart/element/runtime_type_equality_test.dart b/pkg/analyzer/test/src/dart/element/runtime_type_equality_test.dart
index f7aee23..be647f5 100644
--- a/pkg/analyzer/test/src/dart/element/runtime_type_equality_test.dart
+++ b/pkg/analyzer/test/src/dart/element/runtime_type_equality_test.dart
@@ -2,16 +2,12 @@
 // 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/analysis/features.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/src/dart/element/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/elements_types_mixin.dart';
-import '../../../generated/test_analysis_context.dart';
+import '../../../generated/type_system_test.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -20,26 +16,7 @@
 }
 
 @reflectiveTest
-class RuntimeTypeEqualityTypeTest with ElementsTypesMixin {
-  @override
-  late final TypeProvider typeProvider;
-
-  late final TypeSystemImpl typeSystem;
-
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
-  }
-
-  void setUp() {
-    var analysisContext = TestAnalysisContext(
-      featureSet: testFeatureSet,
-    );
-    typeProvider = analysisContext.typeProviderNonNullableByDefault;
-    typeSystem = analysisContext.typeSystemNonNullableByDefault;
-  }
-
+class RuntimeTypeEqualityTypeTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _equal(dynamicNone, dynamicNone);
     _notEqual(dynamicNone, voidNone);
diff --git a/pkg/analyzer/test/src/dart/element/subtype_test.dart b/pkg/analyzer/test/src/dart/element/subtype_test.dart
index 4063e9f..89411e9 100644
--- a/pkg/analyzer/test/src/dart/element/subtype_test.dart
+++ b/pkg/analyzer/test/src/dart/element/subtype_test.dart
@@ -2,7 +2,6 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -23,13 +22,6 @@
 
 @reflectiveTest
 class NonNullableSubtypingCompoundTest extends _SubtypingCompoundTestBase {
-  @override
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
-  }
-
   test_dynamic() {
     var equivalents = <DartType>[
       voidNone,
@@ -5990,7 +5982,7 @@
   }
 }
 
-class _SubtypingTestBase extends AbstractTypeSystemNullSafetyTest {}
+class _SubtypingTestBase extends AbstractTypeSystemTest {}
 
 class _TypeParameterCollector extends TypeVisitor<void> {
   final Set<String> typeParameters = {};
diff --git a/pkg/analyzer/test/src/dart/element/top_merge_test.dart b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
index 44ec079..f726cc9 100644
--- a/pkg/analyzer/test/src/dart/element/top_merge_test.dart
+++ b/pkg/analyzer/test/src/dart/element/top_merge_test.dart
@@ -2,15 +2,11 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/elements_types_mixin.dart';
-import '../../../generated/test_analysis_context.dart';
+import '../../../generated/type_system_test.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -19,7 +15,7 @@
 }
 
 @reflectiveTest
-class TopMergeTest extends _Base {
+class TopMergeTest extends AbstractTypeSystemTest {
   test_differentStructure() {
     _checkThrows(
       intNone,
@@ -341,22 +337,3 @@
     }, throwsA(anything));
   }
 }
-
-abstract class _Base with ElementsTypesMixin {
-  @override
-  late final TypeProvider typeProvider;
-
-  late final TypeSystemImpl typeSystem;
-
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting();
-  }
-
-  void setUp() {
-    var analysisContext = TestAnalysisContext(
-      featureSet: testFeatureSet,
-    );
-    typeProvider = analysisContext.typeProviderLegacy;
-    typeSystem = analysisContext.typeSystemLegacy;
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
index a096499..0469fb8 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -480,7 +480,7 @@
   }
 }
 
-class _Base extends AbstractTypeSystemNullSafetyTest {
+class _Base extends AbstractTypeSystemTest {
   void assertType(DartType type, String expected) {
     var typeStr = _typeStr(type);
     expect(typeStr, expected);
diff --git a/pkg/analyzer/test/src/dart/element/type_bounded_test.dart b/pkg/analyzer/test/src/dart/element/type_bounded_test.dart
index e851ca6..bf625dc 100644
--- a/pkg/analyzer/test/src/dart/element/type_bounded_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_bounded_test.dart
@@ -16,7 +16,7 @@
 }
 
 @reflectiveTest
-class DynamicBoundedTest extends AbstractTypeSystemNullSafetyTest {
+class DynamicBoundedTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _assertDynamicBounded(dynamicNone);
   }
@@ -97,7 +97,7 @@
 }
 
 @reflectiveTest
-class FunctionBoundedTest extends AbstractTypeSystemNullSafetyTest {
+class FunctionBoundedTest extends AbstractTypeSystemTest {
   test_dynamic() {
     _assertNotFunctionBounded(dynamicNone);
   }
diff --git a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
index bed7bd4..8695591 100644
--- a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
@@ -18,7 +18,7 @@
 }
 
 @reflectiveTest
-class TypeConstraintGathererTest extends AbstractTypeSystemNullSafetyTest {
+class TypeConstraintGathererTest extends AbstractTypeSystemTest {
   late final TypeParameterElement T;
   late final TypeParameterType T_none;
   late final TypeParameterType T_question;
diff --git a/pkg/analyzer/test/src/dart/element/type_parameter_element_test.dart b/pkg/analyzer/test/src/dart/element/type_parameter_element_test.dart
index 69ceb64..bf8d4c0 100644
--- a/pkg/analyzer/test/src/dart/element/type_parameter_element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_parameter_element_test.dart
@@ -16,7 +16,7 @@
 }
 
 @reflectiveTest
-class TypeParameterElementTest extends AbstractTypeSystemNullSafetyTest {
+class TypeParameterElementTest extends AbstractTypeSystemTest {
   test_equal_elementElement_sameLocation() {
     var T1 = typeParameter('T');
     var T2 = typeParameter('T');
@@ -45,7 +45,7 @@
 }
 
 @reflectiveTest
-class TypeParameterTypeTest extends AbstractTypeSystemNullSafetyTest {
+class TypeParameterTypeTest extends AbstractTypeSystemTest {
   test_equal_equalElements() {
     var T1 = typeParameter('T');
     var T2 = typeParameter('T');
diff --git a/pkg/analyzer/test/src/dart/element/type_references_any_test.dart b/pkg/analyzer/test/src/dart/element/type_references_any_test.dart
index 6a45016..69ba48f 100644
--- a/pkg/analyzer/test/src/dart/element/type_references_any_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_references_any_test.dart
@@ -17,7 +17,7 @@
 }
 
 @reflectiveTest
-class TypeReferencesAnyTest extends AbstractTypeSystemNullSafetyTest {
+class TypeReferencesAnyTest extends AbstractTypeSystemTest {
   late TypeParameterElement T;
   late TypeParameterType T_none;
 
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index c68511d..5f956f5 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -2,7 +2,6 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -32,13 +31,6 @@
   static final Map<String, StackTrace> _isMoreBottomChecked = {};
   static final Map<String, StackTrace> _isMoreTopChecked = {};
 
-  @override
-  FeatureSet get testFeatureSet {
-    return FeatureSet.forTesting(
-      additionalFeatures: [Feature.non_nullable],
-    );
-  }
-
   void isBottom(DartType type) {
     expect(typeSystem.isBottom(type), isTrue, reason: _typeString(type));
   }
@@ -3347,7 +3339,7 @@
 }
 
 @reflectiveTest
-class _BoundsTestBase extends AbstractTypeSystemNullSafetyTest {
+class _BoundsTestBase extends AbstractTypeSystemTest {
   void _assertBottom(DartType type) {
     if (!typeSystem.isBottom(type)) {
       fail('isBottom must be true: ' + _typeString(type));
diff --git a/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart b/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart
index 690050e..c2fe3b1 100644
--- a/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart
+++ b/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart
@@ -2,10 +2,8 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/resolver/exit_detector.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -145,11 +143,6 @@
 /// See [ExitDetectorResolvedStatementTest] for tests that require the AST to be resolved.
 @reflectiveTest
 class ExitDetectorParsedStatementTest extends ParseBase {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = FeatureSet.forTesting(
-        sdkVersion: '2.13', additionalFeatures: [Feature.constructor_tearoffs]);
-
   test_asExpression() async {
     _assertFalse('a as Object;');
   }
diff --git a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
index ebd3043..6df3560 100644
--- a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
@@ -17,6 +17,21 @@
 @reflectiveTest
 class ConstWithTypeParametersConstructorTearoffTest
     extends PubPackageResolutionTest {
+  test_asExpression_functionType() async {
+    await assertErrorsInCode('''
+void f<T>(T a) {}
+void g() {
+  const [f as void Function<T>(T, [int])];
+}
+''', [
+      // This error is reported because the cast fails if the type on the right
+      // has type parameters.
+      // TODO(srawlins): Deduplicate these two errors.
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 38, 31),
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 60, 1),
+    ]);
+  }
+
   test_direct() async {
     await assertErrorsInCode('''
 class A<T> {
@@ -45,6 +60,18 @@
     ]);
   }
 
+  test_isExpression_functionType() async {
+    await assertErrorsInCode('''
+class A<T> {
+  void m() {
+    const [false is void Function(T)];
+  }
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 60, 1),
+    ]);
+  }
+
   test_nonConst() async {
     await assertNoErrorsInCode('''
 class A<T> {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
index 5d1c5a6..250479b 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
@@ -765,6 +765,19 @@
 ''');
   }
 
+  test_topLevelVariable_result_unusedInDoc() async {
+    // https://github.com/dart-lang/sdk/issues/47181
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+int get f => 1;
+
+/// I love [f].
+int g = 1;
+''');
+  }
+
   test_topLevelVariable_returned() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
index 9b95376..887e3d9 100644
--- a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -308,9 +309,9 @@
 ''', [ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS], '''
 class A<in X> {}
 ''',
-        featureSet: FeatureSet.forTesting(
-          sdkVersion: '2.5.0',
-          additionalFeatures: [Feature.variance],
+        featureSet: FeatureSet.fromEnableFlags2(
+          sdkLanguageVersion: ExperimentStatus.currentVersion,
+          flags: [EnableString.variance],
         ));
   }
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
index c743709..1cd18d7 100644
--- a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -2,7 +2,6 @@
 // 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/analysis/features.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -250,9 +249,7 @@
 f(x) => l?[x
 ''', [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN], '''
 f(x) => l?[x];
-''',
-        featureSet: FeatureSet.forTesting(
-            sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]));
+''');
   }
 
   void test_listLiteral_inner_last() {
diff --git a/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart b/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
index 9fd3a24..f6afa71 100644
--- a/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
+++ b/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
@@ -2,8 +2,6 @@
 // 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/analysis/features.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/summary2/ast_text_printer.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -13,7 +11,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AstTextPrinterTest);
-    defineReflectiveTests(AstTextPrinterWithNullSafetyTest);
   });
 }
 
@@ -79,6 +76,12 @@
 ''');
   }
 
+  test_genericFunctionType_question() async {
+    assertParseCodeAndPrintAst(this, '''
+void Function()? a;
+''');
+  }
+
   test_ifElement_then() async {
     assertParseCodeAndPrintAst(this, r'''
 var _ = [1, if (true) 2, 3];
@@ -121,20 +124,6 @@
 var _ = [1, ...?[2, 3], 4];
 ''');
   }
-}
-
-@reflectiveTest
-class AstTextPrinterWithNullSafetyTest extends ParseBase {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..contextFeatures = FeatureSet.forTesting(
-        sdkVersion: '2.10.0', additionalFeatures: [Feature.non_nullable]);
-
-  test_genericFunctionType_question() async {
-    assertParseCodeAndPrintAst(this, '''
-void Function()? a;
-''');
-  }
 
   test_typeName_question() async {
     assertParseCodeAndPrintAst(this, '''
diff --git a/pkg/analyzer/test/util/id_testing_helper.dart b/pkg/analyzer/test/util/id_testing_helper.dart
index f192694..b1317f0c 100644
--- a/pkg/analyzer/test/util/id_testing_helper.dart
+++ b/pkg/analyzer/test/util/id_testing_helper.dart
@@ -29,15 +29,12 @@
 /// Test configuration used for testing the analyzer with constant evaluation.
 final TestConfig analyzerConstantUpdate2018Config = TestConfig(
     analyzerMarker, 'analyzer with constant-update-2018',
-    featureSet: FeatureSet.forTesting(
-        sdkVersion: '2.2.2',
-        additionalFeatures: [Feature.constant_update_2018]));
+    featureSet: FeatureSet.latestLanguageVersion());
 
 /// Test configuration used for testing the analyzer with NNBD.
 final TestConfig analyzerNnbdConfig = TestConfig(
     analyzerMarker, 'analyzer with NNBD',
-    featureSet: FeatureSet.forTesting(
-        sdkVersion: '2.2.2', additionalFeatures: [Feature.non_nullable]));
+    featureSet: FeatureSet.latestLanguageVersion());
 
 /// A fake absolute directory used as the root of a memory-file system in ID
 /// tests.
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
index 1413ae0..87457bc 100644
--- a/pkg/compiler/lib/src/universe/world_impact.dart
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -247,13 +247,13 @@
 
   @override
   void registerDynamicUse(DynamicUse dynamicUse) {
-    _dynamicUses ??= Setlet.from(worldImpact.dynamicUses);
+    _dynamicUses ??= Setlet.of(worldImpact.dynamicUses);
     _dynamicUses.add(dynamicUse);
   }
 
   @override
   void registerTypeUse(TypeUse typeUse) {
-    _typeUses ??= Setlet.from(worldImpact.typeUses);
+    _typeUses ??= Setlet.of(worldImpact.typeUses);
     _typeUses.add(typeUse);
   }
 
@@ -264,7 +264,7 @@
 
   @override
   void registerStaticUse(StaticUse staticUse) {
-    _staticUses ??= Setlet.from(worldImpact.staticUses);
+    _staticUses ??= Setlet.of(worldImpact.staticUses);
     _staticUses.add(staticUse);
   }
 
@@ -280,7 +280,7 @@
 
   @override
   void registerConstantUse(ConstantUse constantUse) {
-    _constantUses ??= Setlet.from(worldImpact.constantUses);
+    _constantUses ??= Setlet.of(worldImpact.constantUses);
     _constantUses.add(constantUse);
   }
 
diff --git a/pkg/compiler/lib/src/util/maplet.dart b/pkg/compiler/lib/src/util/maplet.dart
index 05d7c4c..1afe289 100644
--- a/pkg/compiler/lib/src/util/maplet.dart
+++ b/pkg/compiler/lib/src/util/maplet.dart
@@ -30,7 +30,7 @@
 
   Maplet();
 
-  Maplet.from(Maplet<K, V> other) {
+  Maplet.of(Maplet<K, V> other) {
     other.forEach((K key, V value) {
       this[key] = value;
     });
diff --git a/pkg/compiler/lib/src/util/setlet.dart b/pkg/compiler/lib/src/util/setlet.dart
index c7aef0d..f44b330 100644
--- a/pkg/compiler/lib/src/util/setlet.dart
+++ b/pkg/compiler/lib/src/util/setlet.dart
@@ -26,7 +26,7 @@
 
   Setlet();
 
-  Setlet.from(Iterable<E> elements) {
+  Setlet.of(Iterable<E> elements) {
     addAll(elements);
   }
 
@@ -209,8 +209,10 @@
   @override
   void removeWhere(bool test(E element)) {
     if (_extra == null) {
-      if (test(_contents)) {
-        _contents = _MARKER;
+      if (_MARKER != _contents) {
+        if (test(_contents)) {
+          _contents = _MARKER;
+        }
       }
     } else if (_MARKER == _extra) {
       _contents.removeWhere(test);
@@ -273,11 +275,11 @@
 
   @override
   Setlet<E> intersection(Set<Object?> other) =>
-      Setlet<E>.from(this.where((e) => other.contains(e)));
+      Setlet.of(this.where((e) => other.contains(e)));
 
   @override
   Setlet<E> difference(Set<Object?> other) =>
-      Setlet<E>.from(this.where((e) => !other.contains(e)));
+      Setlet.of(this.where((e) => !other.contains(e)));
 
   @override
   Setlet<E> toSet() {
diff --git a/pkg/compiler/test/model/maplet_test.dart b/pkg/compiler/test/model/maplet_test.dart
index 1a6e66e..fe9a25f 100644
--- a/pkg/compiler/test/model/maplet_test.dart
+++ b/pkg/compiler/test/model/maplet_test.dart
@@ -2,19 +2,19 @@
 // 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
+// @dart = 2.12
 
 import "package:expect/expect.dart";
 import "package:compiler/src/util/maplet.dart";
 
-main() {
+void main() {
   for (int i = 1; i <= 32; i++) {
     test(i);
   }
 }
 
-test(int size) {
-  var maplet = new Maplet();
+void test(int size) {
+  final maplet = Maplet<int?, String>();
   for (int i = 0; i < size; i++) {
     Expect.isTrue(maplet.isEmpty == (i == 0));
     maplet[i] = '$i';
diff --git a/pkg/compiler/test/model/setlet_test.dart b/pkg/compiler/test/model/setlet_test.dart
index a58f6ce..2b212ba 100644
--- a/pkg/compiler/test/model/setlet_test.dart
+++ b/pkg/compiler/test/model/setlet_test.dart
@@ -2,13 +2,13 @@
 // 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
+// @dart = 2.12
 
 import "package:expect/expect.dart";
 import 'dart:collection';
 import 'package:compiler/src/util/setlet.dart';
 
-main() {
+void main() {
   for (int i = 1; i <= 32; i++) {
     test(i);
   }
@@ -16,8 +16,8 @@
   testAllLikeSet();
 }
 
-test(int size) {
-  var setlet = new Setlet();
+void test(int size) {
+  final setlet = Setlet<int?>();
   for (int i = 0; i < size; i++) {
     Expect.isTrue(setlet.isEmpty == (i == 0));
     setlet.add(i);
@@ -73,10 +73,10 @@
   }
 }
 
-testAllLikeSet() {
+void testAllLikeSet() {
   // For a variety of inputs and operations, test that Setlet behaves just like
   // Set.
-  var samples = [
+  final List<List<int>> samples = [
     [],
     [1],
     [1, 2],
@@ -115,33 +115,36 @@
   }
 }
 
-testSetXElement(name, fn, a, b) {
-  var set1 = new LinkedHashSet.from(a);
-  var setlet1 = new Setlet.from(a);
+void testSetXElement<E, R>(
+    String name, R Function(Set<E>, E) fn, Iterable<E> a, E b) {
+  final set1 = LinkedHashSet.of(a);
+  final setlet1 = Setlet.of(a);
 
-  var setResult = fn(set1, b);
-  var setletResult = fn(setlet1, b);
+  final setResult = fn(set1, b);
+  final setletResult = fn(setlet1, b);
 
-  var operationName = '$name $a $b';
+  final operationName = '$name $a $b';
   checkResult(operationName, setResult, setletResult);
   checkModifications(operationName, set1, setlet1);
 }
 
-testSetXSet(name, fn, a, b) {
-  var set1 = new LinkedHashSet.from(a);
-  var set2 = new LinkedHashSet.from(b);
-  var setlet1 = new Setlet.from(a);
-  var setlet2 = new Setlet.from(b);
+void testSetXSet<E, R>(
+    String name, R Function(Set<E>, Set<E>) fn, Iterable<E> a, Iterable<E> b) {
+  final set1 = LinkedHashSet.of(a);
+  final set2 = LinkedHashSet.of(b);
+  final setlet1 = Setlet.of(a);
+  final setlet2 = Setlet.of(b);
 
-  var setResult = fn(set1, set2);
-  var setletResult = fn(setlet1, setlet2);
+  final setResult = fn(set1, set2);
+  final setletResult = fn(setlet1, setlet2);
 
-  var operationName = '$name $a $b';
+  final operationName = '$name $a $b';
   checkResult(operationName, setResult, setletResult);
   checkModifications(operationName, set1, setlet1);
 }
 
-checkResult(operationName, setResult, setletResult) {
+void checkResult(
+    String operationName, dynamic setResult, dynamic setletResult) {
   if (setResult == null || setResult is bool || setResult is num) {
     Expect.equals(setResult, setletResult, '$operationName');
   } else if (setResult is Iterable) {
@@ -152,12 +155,15 @@
         setResult.length, setletResult.length, '$operationName: same length');
     Expect.listEquals(setResult.toList(), setletResult.toList(),
         '$operationName: same toList() result');
+    Expect.listEquals([...setResult], [...setletResult],
+        '$operationName: same spread result');
   } else {
     Expect.isFalse(true, '$operationName: unexpected result type');
   }
 }
 
-checkModifications(operationName, setReceiver, setletReceiver) {
+void checkModifications<E>(
+    String operationName, Set<E> setReceiver, Set<E> setletReceiver) {
   Expect.equals(setReceiver.length, setletReceiver.length,
       '$operationName: same post-operation receiver length');
   Expect.listEquals(setReceiver.toList(), setletReceiver.toList(),
diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart
index 2f68e15f..6430602 100644
--- a/pkg/front_end/test/incremental_suite.dart
+++ b/pkg/front_end/test/incremental_suite.dart
@@ -26,7 +26,7 @@
     show ExperimentalFlag, experimentEnabledVersion;
 
 import "package:front_end/src/api_prototype/memory_file_system.dart"
-    show MemoryFileSystem;
+    show MemoryFileSystem, MemoryFileSystemEntity;
 
 import 'package:front_end/src/base/nnbd_mode.dart' show NnbdMode;
 
@@ -308,7 +308,7 @@
   final Uri base = Uri.parse("org-dartlang-test:///");
   final Uri sdkSummaryUri = base.resolve(sdkSummary);
 
-  MemoryFileSystem fs = new MemoryFileSystem(base);
+  TestMemoryFileSystem fs = new TestMemoryFileSystem(base);
   fs.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
 
   // Setup all sources
@@ -508,7 +508,7 @@
       }
 
       if (brandNewWorld) {
-        fs = new MemoryFileSystem(base);
+        fs = new TestMemoryFileSystem(base);
       }
       fs!.entityForUri(sdkSummaryUri).writeAsBytesSync(sdkSummaryData);
       bool expectInitializeFromDill = false;
@@ -1991,3 +1991,19 @@
     }
   }
 }
+
+class TestMemoryFileSystem extends MemoryFileSystem {
+  TestMemoryFileSystem(Uri currentDirectory) : super(currentDirectory);
+
+  @override
+  MemoryFileSystemEntity entityForUri(Uri uri) {
+    // Try to "sanitize" the uri as a real file system does, namely
+    // "a/b.dart" and "a//b.dart" returns the same file.
+    if (uri.pathSegments.contains("")) {
+      Uri newUri = uri.replace(
+          pathSegments: uri.pathSegments.where((element) => element != ""));
+      return super.entityForUri(newUri);
+    }
+    return super.entityForUri(uri);
+  }
+}
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 398070d..82edba1 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -825,6 +825,7 @@
 runtimes
 rv
 sandboxed
+sanitize
 saves
 scans
 scheduler
@@ -926,6 +927,7 @@
 timer
 timings
 tinv
+tk
 told
 touch
 tpt
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart
new file mode 100644
index 0000000..a45bc22
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, 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 {
+  final int Function(int) x;
+  const A(bool b)
+      : x = (b
+            ? id
+            : other)<int>; // OK, `(...)<T1..Tk>` is potentially constant.
+}
+
+X id<X>(X x) => x;
+X other<X>(X x) => throw '$x';
+
+void main() {
+  const c1 =
+      id<int>; // Already supported prior to the addition on this feature.
+  const c2 =
+      id; // Make `c2` a constant expression whose value is a function object.
+  const c3 = c2<int>; // OK, perform generic function instantiation on `c2`.
+  const c4 = A(
+      true); // OK, `(b ? id : other)<int>` is constant after substitution `b` -> `true`.
+  print('$c1, $c2, $c3, $c4');
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.strong.expect
new file mode 100644
index 0000000..a23b6b4
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.strong.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = (b ?{<X extends core::Object? = dynamic>(X%) → X%} #C1 : #C2)<core::int>, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C3}, ${#C1}, ${#C3}, ${#C4}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = static-tearoff self::other
+  #C3 = instantiation self::id <core::int>
+  #C4 = self::A {x:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154a.dart:
+- A. (from org-dartlang-testcase:///issue47154a.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.strong.transformed.expect
new file mode 100644
index 0000000..a23b6b4
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = (b ?{<X extends core::Object? = dynamic>(X%) → X%} #C1 : #C2)<core::int>, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C3}, ${#C1}, ${#C3}, ${#C4}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = static-tearoff self::other
+  #C3 = instantiation self::id <core::int>
+  #C4 = self::A {x:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154a.dart:
+- A. (from org-dartlang-testcase:///issue47154a.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.textual_outline.expect
new file mode 100644
index 0000000..17cdb52
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  final int Function(int) x;
+  const A(bool b) : x = (b ? id : other)<int>;
+}
+
+X id<X>(X x) => x;
+X other<X>(X x) => throw '$x';
+void main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6598e5a
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+X id<X>(X x) => x;
+X other<X>(X x) => throw '$x';
+
+class A {
+  const A(bool b) : x = (b ? id : other)<int>;
+  final int Function(int) x;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.expect
new file mode 100644
index 0000000..55aaf0f
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = (b ?{<X extends core::Object? = dynamic>(X%) → X%} #C1 : #C2)<core::int>, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C3}, ${#C1}, ${#C3}, ${#C4}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = static-tearoff self::other
+  #C3 = instantiation self::id <core::int*>
+  #C4 = self::A {x:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154a.dart:
+- A. (from org-dartlang-testcase:///issue47154a.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.outline.expect
new file mode 100644
index 0000000..efc3521
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.outline.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = (b ?{<X extends core::Object? = dynamic>(X%) → X%} self::id : self::other)<core::int>, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  ;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  ;
+static method main() → void
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: StaticTearOff @ org-dartlang-testcase:///issue47154a.dart:9:15 -> StaticTearOffConstant(id)
+Evaluated: StaticTearOff @ org-dartlang-testcase:///issue47154a.dart:10:15 -> StaticTearOffConstant(other)
+Extra constant evaluation: evaluated: 5, effectively constant: 2
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.transformed.expect
new file mode 100644
index 0000000..55aaf0f
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154a.dart.weak.transformed.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = (b ?{<X extends core::Object? = dynamic>(X%) → X%} #C1 : #C2)<core::int>, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C3}, ${#C1}, ${#C3}, ${#C4}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = static-tearoff self::other
+  #C3 = instantiation self::id <core::int*>
+  #C4 = self::A {x:#C3}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154a.dart:
+- A. (from org-dartlang-testcase:///issue47154a.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart
new file mode 100644
index 0000000..bc54add
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, 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 {
+  final int Function(int) x;
+  const A(bool b)
+      : x = (b ? id : other); // OK, `(...)<T1..Tk>` is potentially constant.
+}
+
+X id<X>(X x) => x;
+X other<X>(X x) => throw '$x';
+
+void main() {
+  const int Function(int) c1 =
+      id; // Already supported prior to the addition on this feature.
+  const c2 =
+      id; // Make `c2` a constant expression whose value is a function object.
+  const int Function(int) c3 =
+      c2; // OK, perform generic function instantiation on `c2`.
+  const c4 = A(
+      true); // OK, `(b ? id : other)<int>` is constant after substitution `b` -> `true`.
+  print('$c1, $c2, $c3, $c4');
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.strong.expect
new file mode 100644
index 0000000..41ae260
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.strong.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = b ?{(core::int) → core::int} #C2 : #C4, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C2}, ${#C1}, ${#C2}, ${#C5}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = instantiation self::id <core::int>
+  #C3 = static-tearoff self::other
+  #C4 = instantiation self::other <core::int>
+  #C5 = self::A {x:#C2}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154b.dart:
+- A. (from org-dartlang-testcase:///issue47154b.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.strong.transformed.expect
new file mode 100644
index 0000000..41ae260
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = b ?{(core::int) → core::int} #C2 : #C4, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C2}, ${#C1}, ${#C2}, ${#C5}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = instantiation self::id <core::int>
+  #C3 = static-tearoff self::other
+  #C4 = instantiation self::other <core::int>
+  #C5 = self::A {x:#C2}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154b.dart:
+- A. (from org-dartlang-testcase:///issue47154b.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.textual_outline.expect
new file mode 100644
index 0000000..5d52a74
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+  final int Function(int) x;
+  const A(bool b) : x = (b ? id : other);
+}
+
+X id<X>(X x) => x;
+X other<X>(X x) => throw '$x';
+void main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e5a005e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+X id<X>(X x) => x;
+X other<X>(X x) => throw '$x';
+
+class A {
+  const A(bool b) : x = (b ? id : other);
+  final int Function(int) x;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.expect
new file mode 100644
index 0000000..535ad97
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = b ?{(core::int) → core::int} #C2 : #C4, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C2}, ${#C1}, ${#C2}, ${#C5}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = instantiation self::id <core::int*>
+  #C3 = static-tearoff self::other
+  #C4 = instantiation self::other <core::int*>
+  #C5 = self::A {x:#C2}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154b.dart:
+- A. (from org-dartlang-testcase:///issue47154b.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.outline.expect
new file mode 100644
index 0000000..ca341b8
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.outline.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = b ?{(core::int) → core::int} self::id<core::int> : self::other<core::int>, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  ;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  ;
+static method main() → void
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: Instantiation @ org-dartlang-testcase:///issue47154b.dart:8:18 -> InstantiationConstant(id<int*>)
+Evaluated: Instantiation @ org-dartlang-testcase:///issue47154b.dart:8:23 -> InstantiationConstant(other<int*>)
+Extra constant evaluation: evaluated: 4, effectively constant: 2
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.transformed.expect
new file mode 100644
index 0000000..535ad97
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue47154b.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/  {
+  final field (core::int) → core::int x;
+  const constructor •(core::bool b) → self::A
+    : self::A::x = b ?{(core::int) → core::int} #C2 : #C4, super core::Object::•()
+    ;
+}
+static method id<X extends core::Object? = dynamic>(self::id::X% x) → self::id::X%
+  return x;
+static method other<X extends core::Object? = dynamic>(self::other::X% x) → self::other::X%
+  return throw "${x}";
+static method main() → void {
+  core::print("${#C2}, ${#C1}, ${#C2}, ${#C5}");
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+  #C2 = instantiation self::id <core::int*>
+  #C3 = static-tearoff self::other
+  #C4 = instantiation self::other <core::int*>
+  #C5 = self::A {x:#C2}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47154b.dart:
+- A. (from org-dartlang-testcase:///issue47154b.dart:7:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/incremental.status b/pkg/front_end/testcases/incremental.status
index 1c24c9e..f0401a1 100644
--- a/pkg/front_end/testcases/incremental.status
+++ b/pkg/front_end/testcases/incremental.status
@@ -6,3 +6,5 @@
 
 # http://dartbug.com/41812#issuecomment-684825703
 #strongmode_mixins_2: Crash
+
+changing_modules_16: Crash
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental/changing_modules_16.yaml b/pkg/front_end/testcases/incremental/changing_modules_16.yaml
new file mode 100644
index 0000000..69ad3b9
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/changing_modules_16.yaml
@@ -0,0 +1,49 @@
+# Copyright (c) 2021, 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.md file.
+
+# Reproduction of https://github.com/dart-lang/sdk/issues/47176
+# Compile an application with modules where one module has imported another
+# module with too many slashes. Now try to import it correctly.
+# This is essentially equivalent to not loading a needed component.
+
+type: newworld
+target: DDC
+modules:
+  moduleA:
+    moduleA/x/lib.dart: |
+      void foo() { }
+    moduleA/.packages: |
+      moduleA:.
+  moduleB:
+    moduleB/x/lib.dart: |
+      // Mind the double-slash! (on Windows this could probably also be a change
+      // in case (e.g 'lib' vs 'Lib')).
+      import 'package:moduleA/x//lib.dart';
+      void bar() { }
+    moduleB/.packages: |
+      moduleA:../moduleA
+      moduleB:.
+worlds:
+  - entry: main.dart
+    fromComponent: true
+    sources:
+      main.dart: |
+        import 'package:moduleB/x/lib.dart';
+        main() {
+          bar();
+        }
+      .packages: |
+        moduleA:moduleA
+        moduleB:moduleB
+    modules:
+      - moduleA
+      - moduleB
+    expectedLibraryCount: 3
+    neededDillLibraries:
+      - package:module/x/lib.dart
+    expectedContent:
+      org-dartlang-test:///main.dart:
+        - Procedure main
+      package:module/lib.dart:
+        - Procedure foo
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index a4f43e2..5f81f25 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -185,11 +185,6 @@
     var inheritanceManager = InheritanceManager3();
     // TODO(paulberry): is it a bad idea to throw away errors?
     var errorListener = AnalysisErrorListener.NULL_LISTENER;
-    // TODO(paulberry): once the feature is no longer experimental, change the
-    // way we enable it in the resolver.
-    // ignore: invalid_use_of_visible_for_testing_member
-    var featureSet = FeatureSet.forTesting(
-        sdkVersion: '2.6.0', additionalFeatures: [Feature.non_nullable]);
     _resolver = ResolverVisitorForMigration(
         inheritanceManager,
         definingLibrary,
@@ -197,7 +192,10 @@
         typeProvider,
         errorListener,
         _typeSystem,
-        featureSet,
+        FeatureSet.fromEnableFlags2(
+          sdkLanguageVersion: Feature.non_nullable.releaseVersion!,
+          flags: [],
+        ),
         migrationResolutionHooks);
   }
 
diff --git a/pkg/vm/lib/transformations/ffi_native.dart b/pkg/vm/lib/transformations/ffi_native.dart
index ff405f8..3d44d46 100644
--- a/pkg/vm/lib/transformations/ffi_native.dart
+++ b/pkg/vm/lib/transformations/ffi_native.dart
@@ -102,22 +102,26 @@
     final DartType dartType =
         node.function.computeThisFunctionType(Nullability.nonNullable);
     // Double Function(Double)
-    final nativeType = annotationConst.typeArguments[0];
+    final nativeType = annotationConst.typeArguments[0] as FunctionType;
     // InterfaceType(NativeFunction<Double Function(Double)>*)
     final DartType nativeInterfaceType =
         InterfaceType(nativeFunctionClass, Nullability.legacy, [nativeType]);
 
+    // Derive number of arguments from the native function signature.
+    final args_n = nativeType.positionalParameters.length;
+
     // TODO(dartbug.com/31579): Add `..fileOffset`s once we can handle these in
     // patch files.
 
-    // _ffi_resolver('dart:math', 'Math_sqrt')
+    // _ffi_resolver('dart:math', 'Math_sqrt', 1)
     final resolverInvocation = FunctionInvocation(
         FunctionAccessKind.FunctionType,
         StaticGet(resolverField),
         Arguments([
           ConstantExpression(
               StringConstant(currentLibrary!.importUri.toString())),
-          ConstantExpression(functionName)
+          ConstantExpression(functionName),
+          ConstantExpression(IntConstant(args_n)),
         ]),
         functionType: resolverField.type as FunctionType);
 
@@ -151,7 +155,7 @@
       parent.addField(funcPtrField);
     } else {
       throw 'Unexpected parent of @FfiNative function. '
-        'Expected Class or Library, but found ${parent}.';
+          'Expected Class or Library, but found ${parent}.';
     }
 
     // _@FfiNative__square_root(x)
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 13e7440..f37aa3a 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1397,9 +1397,8 @@
       return _makeUnreachableCall([]);
     } else {
       if (!shaker.isMemberBodyReachable(node.target)) {
-        // Annotations could contain references to constant fields.
-        assert((node.target is Field) && (node.target as Field).isConst);
-        shaker.addUsedMember(node.target);
+        throw '${node.runtimeType} "$node" uses unreachable member '
+            '${node.target} at ${node.location}';
       }
       return node;
     }
@@ -1435,9 +1434,8 @@
       return _makeUnreachableCall(_flattenArguments(node.arguments));
     } else {
       if (!shaker.isMemberBodyReachable(node.target)) {
-        // Annotations could contain references to const constructors.
-        assert(node.isConst);
-        shaker.addUsedMember(node.target);
+        throw '${node.runtimeType} "$node" uses unreachable member '
+            '${node.target} at ${node.location}';
       }
       return node;
     }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart
index 602299f..1311d36 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart
@@ -9,4 +9,4 @@
   if (list.isNotEmpty) {
     new Class().method(null as dynamic);
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
index 0e15b41..0e12dc6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
@@ -17,12 +17,12 @@
 import "dart:core" as core;
 
 abstract class Enum extends core::Object implements core::Enum {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3267]  abstract get /*isLegacy*/ index() → core::int;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3265]  abstract get /*isLegacy*/ index() → core::int;
 }
 class Class extends core::Object {
   synthetic constructor •() → self::Class
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3268,getterSelectorId:3269]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3266,getterSelectorId:3267]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
     return [@vm.inferred-type.metadata=!] e.{self::Enum::index}{core::int};
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart
index 951e2e9..e5600e4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.lib.dart
@@ -6,4 +6,4 @@
 
 class Class {
   int method(Enum e) => e.index;
-}
\ No newline at end of file
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart
index 1abc669..e995a89 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart
@@ -37,4 +37,4 @@
   if (list.isNotEmpty) {
     new ConstClass().method(null as dynamic);
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
index 1f84d00..12268e7 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
@@ -48,12 +48,12 @@
 import "dart:core" as core;
 
 abstract class ConstEnum extends core::Object implements core::Enum {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3273]  abstract get /*isLegacy*/ index() → core::int;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3271]  abstract get /*isLegacy*/ index() → core::int;
 }
 class ConstClass extends core::Object {
   synthetic constructor •() → self::ConstClass
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3274,getterSelectorId:3275]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3272,getterSelectorId:3273]  method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
     return [@vm.inferred-type.metadata=!] e.{self::ConstEnum::index}{core::int};
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart
index af82d68..bc873dc 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.lib.dart
@@ -6,4 +6,4 @@
 
 class ConstClass {
   int method(ConstEnum e) => e.index;
-}
\ No newline at end of file
+}
diff --git a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
index adcdc07..affbe3a 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
@@ -1094,11 +1094,11 @@
   return x;
 }
 
-static void* FfiNativeResolver(const char* name) {
-  if (strcmp(name, "ReturnIntPtr") == 0) {
+static void* FfiNativeResolver(const char* name, uintptr_t args_n) {
+  if (strcmp(name, "ReturnIntPtr") == 0 && args_n == 1) {
     return reinterpret_cast<void*>(ReturnIntPtr);
   }
-  if (strcmp(name, "IsThreadInGenerated") == 0) {
+  if (strcmp(name, "IsThreadInGenerated") == 0 && args_n == 0) {
     return reinterpret_cast<void*>(IsThreadInGenerated);
   }
   // This should be unreachable in tests.
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 861a87f..422e2be 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3046,7 +3046,7 @@
  *
  * See Dart_SetFfiNativeResolver.
  */
-typedef void* (*Dart_FfiNativeResolver)(const char* name);
+typedef void* (*Dart_FfiNativeResolver)(const char* name, uintptr_t args_n);
 
 /*
  * ===========
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index cc4a6ff..239f758 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -276,7 +276,9 @@
 }
 
 // FFI native C function pointer resolver.
-static intptr_t FfiResolve(Dart_Handle lib_url, Dart_Handle name) {
+static intptr_t FfiResolve(Dart_Handle lib_url,
+                           Dart_Handle name,
+                           uintptr_t args_n) {
   DARTSCOPE(Thread::Current());
 
   const String& lib_url_str = Api::UnwrapStringHandle(T->zone(), lib_url);
@@ -296,7 +298,7 @@
     Exceptions::ThrowArgumentError(error);
   }
 
-  auto* f = resolver(function_name.ToCString());
+  auto* f = resolver(function_name.ToCString(), args_n);
   if (f == nullptr) {
     const String& error = String::Handle(String::NewFormatted(
         "Couldn't resolve function: '%s'.", function_name.ToCString()));
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 3ca14d8..f478245 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -67,10 +67,12 @@
 dart/regress_40462_test: SkipSlow
 dart/regress_40753_test: Skip # This test crashes on the bot, but not locally, and infrastructure repeatly fails to locate its coredump.
 dart/trigger_gc_in_native_test: Skip # This test crashes on the bot, but not locally, and infrastructure repeatly fails to locate its coredump.
+dart/use_strip_flag_test: Pass, Slow # This test can take a longer time to complete.
 dart_2/appjit_cha_deopt_test: SkipSlow
 dart_2/regress_40462_test: SkipSlow
 dart_2/regress_40753_test: Skip # This test crashes on the bot, but not locally, and infrastructure repeatly fails to locate its coredump.
 dart_2/trigger_gc_in_native_test: Skip # This test crashes on the bot, but not locally, and infrastructure repeatly fails to locate its coredump.
+dart_2/use_strip_flag_test: Pass, Slow # This test can take a longer time to complete.
 
 [ $compiler == app_jitk ]
 dart/snapshot_version_test: RuntimeError
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index 54fc1b9..0bd184c 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -33,7 +33,8 @@
       signature, function_name, UntaggedFunction::kRegularFunction, true, false,
       false, false, false, owner_class, TokenPosition::kNoSource));
 
-  const String& target_name = String::Handle(String::New("targetFunction"));
+  const String& target_name =
+      String::Handle(Symbols::New(thread, "targetFunction"));
   const intptr_t kTypeArgsLen = 0;
   const intptr_t kNumArgs = 1;
   const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index c9026d5..c963d44 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -33,7 +33,8 @@
       signature, function_name, UntaggedFunction::kRegularFunction, true, false,
       false, false, false, owner_class, TokenPosition::kNoSource));
 
-  const String& target_name = String::Handle(String::New("targetFunction"));
+  const String& target_name =
+      String::Handle(Symbols::New(thread, "targetFunction"));
   const intptr_t kTypeArgsLen = 0;
   const intptr_t kNumArgs = 1;
   const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index 36c6ec5..ef55b48 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -33,7 +33,8 @@
       signature, function_name, UntaggedFunction::kRegularFunction, true, false,
       false, false, false, owner_class, TokenPosition::kNoSource));
 
-  const String& target_name = String::Handle(String::New("targetFunction"));
+  const String& target_name =
+      String::Handle(Symbols::New(thread, "targetFunction"));
   const intptr_t kTypeArgsLen = 0;
   const intptr_t kNumArgs = 1;
   const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index e5666e3..29cf624 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -33,7 +33,8 @@
       signature, function_name, UntaggedFunction::kRegularFunction, true, false,
       false, false, false, owner_class, TokenPosition::kNoSource));
 
-  const String& target_name = String::Handle(String::New("targetFunction"));
+  const String& target_name =
+      String::Handle(Symbols::New(thread, "targetFunction"));
   const intptr_t kTypeArgsLen = 0;
   const intptr_t kNumArgs = 1;
   const Array& args_descriptor = Array::Handle(ArgumentsDescriptor::NewBoxed(
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 163403a..1f65f74 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1671,8 +1671,11 @@
   RELEASE_ASSERT(CanLoadFromObjectPool(object));
   // Make sure that class CallPattern is able to decode this load from the
   // object pool.
-  const auto index = is_unique ? object_pool_builder().AddObject(object)
-                               : object_pool_builder().FindObject(object);
+  const auto index = is_unique
+                         ? object_pool_builder().AddObject(
+                               object, ObjectPoolBuilderEntry::kPatchable)
+                         : object_pool_builder().FindObject(
+                               object, ObjectPoolBuilderEntry::kNotPatchable);
   LoadWordFromPoolIndex(rd, index, pp, cond);
 }
 
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index d15a27a..cd72ba5 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -555,8 +555,11 @@
     }
   }
   if (CanLoadFromObjectPool(object)) {
-    const intptr_t index = is_unique ? object_pool_builder().AddObject(object)
-                                     : object_pool_builder().FindObject(object);
+    const intptr_t index =
+        is_unique ? object_pool_builder().AddObject(
+                        object, ObjectPoolBuilderEntry::kPatchable)
+                  : object_pool_builder().FindObject(
+                        object, ObjectPoolBuilderEntry::kNotPatchable);
     LoadWordFromPoolIndex(dst, index);
     return;
   }
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 7042a44..d2dc30c 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1287,8 +1287,11 @@
     }
   }
   if (CanLoadFromObjectPool(object)) {
-    const intptr_t index = is_unique ? object_pool_builder().AddObject(object)
-                                     : object_pool_builder().FindObject(object);
+    const intptr_t index =
+        is_unique ? object_pool_builder().AddObject(
+                        object, ObjectPoolBuilderEntry::kPatchable)
+                  : object_pool_builder().FindObject(
+                        object, ObjectPoolBuilderEntry::kNotPatchable);
     LoadWordFromPoolIndex(dst, index);
     return;
   }
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index c4fcdd7..65efc13 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -99,7 +99,7 @@
   if (obj.IsNull()) {
     return 2011;
   }
-  if (obj.IsString() || obj.IsNumber()) {
+  if (obj.IsInstance()) {
     return Instance::Cast(obj).CanonicalizeHash();
   }
   if (obj.IsCode()) {
@@ -112,6 +112,9 @@
   if (obj.IsField()) {
     return dart::String::HashRawSymbol(Field::Cast(obj).name());
   }
+  if (obj.IsICData()) {
+    return ICData::Cast(obj).Hash();
+  }
   // Unlikely.
   return obj.GetClassId();
 }
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 38b1022..fda1251 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -92,86 +92,62 @@
 
 class DartInitializationState {
  public:
-  enum class InitializationState {
-    kUnInitialized = 0,
-    kInitializing = 1,
-    kInitialized = 2,
-    kCleaningup = 3,
-  };
+  uint8_t kUnInitialized = 0;
+  uint8_t kInitializing = 1;
+  uint8_t kInitialized = 2;
+  uint8_t kCleaningup = 3;
 
-  DartInitializationState()
-      : state_(InitializationState::kUnInitialized),
-        in_use_(false),
-        lock_(nullptr) {
-    lock_ = new Monitor();
-  }
+  DartInitializationState() : state_(0), in_use_count_(0) {}
   ~DartInitializationState() {}
 
   bool SetInitializing() {
-    MonitorLocker ml(lock_);
-    if (state_ != InitializationState::kUnInitialized || in_use_) {
-      return false;
-    }
-    state_ = InitializationState::kInitializing;
-    return true;
+    ASSERT(in_use_count_.load() == 0);
+    return state_.compare_exchange_strong(kUnInitialized, kInitializing);
   }
 
   void ResetInitializing() {
-    MonitorLocker ml(lock_);
-    ASSERT((state_ == InitializationState::kInitializing) && !in_use_);
-    state_ = InitializationState::kUnInitialized;
+    ASSERT(in_use_count_.load() == 0);
+    bool result = state_.compare_exchange_strong(kInitializing, kUnInitialized);
+    ASSERT(result);
   }
 
   void SetInitialized() {
-    MonitorLocker ml(lock_);
-    ASSERT((state_ == InitializationState::kInitializing) && !in_use_);
-    state_ = InitializationState::kInitialized;
+    ASSERT(in_use_count_.load() == 0);
+    bool result = state_.compare_exchange_strong(kInitializing, kInitialized);
+    ASSERT(result);
   }
 
-  bool IsInitialized() const {
-    MonitorLocker ml(lock_);
-    return (state_ == InitializationState::kInitialized);
-  }
+  bool IsInitialized() const { return state_.load() == kInitialized; }
 
   bool SetCleaningup() {
-    MonitorLocker ml(lock_);
-    if (state_ != InitializationState::kInitialized) {
-      return false;
-    }
-    state_ = InitializationState::kCleaningup;
-    return true;
+    return state_.compare_exchange_strong(kInitialized, kCleaningup);
   }
 
   void SetUnInitialized() {
-    MonitorLocker ml(lock_);
-    ASSERT(state_ == InitializationState::kCleaningup);
-    while (in_use_) {
-      ml.Wait();
+    while (in_use_count_.load() > 0) {
+      OS::Sleep(1);  // Sleep for 1 millis waiting for it to not be in use.
     }
-    state_ = InitializationState::kUnInitialized;
+    bool result = state_.compare_exchange_strong(kCleaningup, kUnInitialized);
+    ASSERT(result);
   }
 
   bool SetInUse() {
-    MonitorLocker ml(lock_);
-    if (state_ != InitializationState::kInitialized) {
+    if (state_.load() != kInitialized) {
       return false;
     }
-    in_use_ = true;
+    in_use_count_ += 1;
     return true;
   }
 
   void ResetInUse() {
-    MonitorLocker ml(lock_);
-    ASSERT((state_ == InitializationState::kInitialized) ||
-           (state_ == InitializationState::kCleaningup));
-    in_use_ = false;
-    ml.NotifyAll();
+    uint8_t value = state_.load();
+    ASSERT((value == kInitialized) || (value == kCleaningup));
+    in_use_count_ -= 1;
   }
 
  private:
-  InitializationState state_;
-  bool in_use_;
-  Monitor* lock_;
+  std::atomic<uint8_t> state_;
+  std::atomic<uint64_t> in_use_count_;
 };
 static DartInitializationState init_state_;
 
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 2849c6b..4d9d1df 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -9585,8 +9585,9 @@
   return x;
 }
 
-static void* FfiNativeResolver(const char* name) {
+static void* FfiNativeResolver(const char* name, uintptr_t args_n) {
   ASSERT(strcmp(name, "EchoInt") == 0);
+  ASSERT(args_n == 1);
   return reinterpret_cast<void*>(EchoInt);
 }
 
@@ -9628,7 +9629,7 @@
       "Invalid argument(s): Library has no handler: 'file:///test-lib'.");
 }
 
-static void* NopResolver(const char* name) {
+static void* NopResolver(const char* name, uintptr_t args_n) {
   return nullptr;
 }
 
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 7c0cb4b..e1f1be9 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -17,25 +17,18 @@
  public:
   explicit BaseDirectChainedHashMap(Allocator* allocator,
                                     intptr_t initial_size = kInitialSize)
-      : array_size_(0),
-        lists_size_(0),
-        count_(0),
-        array_(NULL),
-        lists_(NULL),
-        free_list_head_(kNil),
-        allocator_(allocator) {
-    ASSERT(Utils::IsPowerOfTwo(initial_size));
-    ResizeLists(initial_size);
+      : allocator_(allocator) {
     Resize(initial_size);
   }
 
   BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other);
 
-  intptr_t Length() const { return count_; }
+  intptr_t Length() const { return next_pair_index_ - deleted_count_; }
 
-  virtual ~BaseDirectChainedHashMap() {
-    allocator_->template Free<HashMapListElement>(array_, array_size_);
-    allocator_->template Free<HashMapListElement>(lists_, lists_size_);
+  ~BaseDirectChainedHashMap() {
+    allocator_->template Free<uint32_t>(hash_table_, hash_table_size_);
+    allocator_->template Free<typename KeyValueTrait::Pair>(pairs_,
+                                                            pairs_size_);
   }
 
   // Assumes that no existing pair in the map has a key equal to [kv.key].
@@ -56,41 +49,35 @@
 
   typename KeyValueTrait::Pair* Lookup(typename KeyValueTrait::Key key) const;
   bool HasKey(typename KeyValueTrait::Key key) const {
-    return Lookup(key) != NULL;
+    return Lookup(key) != nullptr;
   }
 
-  intptr_t Size() const { return count_; }
-  bool IsEmpty() const { return count_ == 0; }
+  intptr_t Size() const { return next_pair_index_ - deleted_count_; }
+  bool IsEmpty() const { return Size() == 0; }
 
-  virtual void Clear() {
-    if (!IsEmpty()) {
-      count_ = 0;
-      InitArray(array_, array_size_);
-      InitArray(lists_, lists_size_);
-      lists_[0].next = kNil;
-      for (intptr_t i = 1; i < lists_size_; ++i) {
-        lists_[i].next = i - 1;
-      }
-      free_list_head_ = lists_size_ - 1;
+  void Clear() {
+    for (uint32_t i = 0; i < hash_table_size_; i++) {
+      hash_table_[i] = kEmpty;
     }
+    for (uint32_t i = 0; i < next_pair_index_; i++) {
+      pairs_[i] = typename KeyValueTrait::Pair();
+    }
+    next_pair_index_ = 0;
+    deleted_count_ = 0;
   }
 
   class Iterator {
    public:
     typename KeyValueTrait::Pair* Next();
 
-    void Reset() {
-      array_index_ = 0;
-      list_index_ = kNil;
-    }
+    void Reset() { pair_index_ = 0; }
 
    private:
     explicit Iterator(const BaseDirectChainedHashMap& map)
-        : map_(map), array_index_(0), list_index_(kNil) {}
+        : map_(map), pair_index_(0) {}
 
     const BaseDirectChainedHashMap& map_;
-    intptr_t array_index_;
-    intptr_t list_index_;
+    uint32_t pair_index_;
 
     template <typename T, typename Bs, typename A>
     friend class BaseDirectChainedHashMap;
@@ -99,35 +86,21 @@
   Iterator GetIterator() const { return Iterator(*this); }
 
  protected:
-  // A linked list of T values.  Stored in arrays.
-  struct HashMapListElement {
-    HashMapListElement() : kv(), next(kNil) {}
-    typename KeyValueTrait::Pair kv;
-    intptr_t next;  // Index in the array of the next list element.
-  };
-  static const intptr_t kNil = -1;  // The end of a linked list
-
-  static void InitArray(HashMapListElement* array, intptr_t size) {
-    for (intptr_t i = 0; i < size; ++i) {
-      array[i] = HashMapListElement();
-    }
-  }
-
-  // Must be a power of 2.
-  static const intptr_t kInitialSize = 16;
+  static constexpr intptr_t kInitialSize = 16;
 
   void Resize(intptr_t new_size);
-  void ResizeLists(intptr_t new_size);
-  uword Bound(uword value) const { return value & (array_size_ - 1); }
 
-  intptr_t array_size_;
-  intptr_t lists_size_;
-  intptr_t count_;             // The number of values stored in the HashMap.
-  HashMapListElement* array_;  // Primary store - contains the first value
-  // with a given hash.  Colliding elements are stored in linked lists.
-  HashMapListElement* lists_;  // The linked lists containing hash collisions.
-  intptr_t free_list_head_;  // Unused elements in lists_ are on the free list.
-  Allocator* allocator_;
+  Allocator* const allocator_;
+  uint32_t* hash_table_ = nullptr;
+  typename KeyValueTrait::Pair* pairs_ = nullptr;
+  uint32_t hash_table_size_ = 0;
+  uint32_t pairs_size_ = 0;
+  uint32_t next_pair_index_ = 0;
+  uint32_t deleted_count_ = 0;
+
+  static constexpr uint32_t kEmpty = kMaxUint32;
+  static constexpr uint32_t kDeleted = kMaxUint32 - 1;
+  static constexpr uint32_t kMaxPairs = kMaxUint32 - 2;
 
  private:
   void operator=(const BaseDirectChainedHashMap& other) = delete;
@@ -137,42 +110,45 @@
 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::BaseDirectChainedHashMap(
     const BaseDirectChainedHashMap& other)
     : B(),
-      array_size_(other.array_size_),
-      lists_size_(other.lists_size_),
-      count_(other.count_),
-      array_(other.allocator_->template Alloc<HashMapListElement>(
-          other.array_size_)),
-      lists_(other.allocator_->template Alloc<HashMapListElement>(
-          other.lists_size_)),
-      free_list_head_(other.free_list_head_),
-      allocator_(other.allocator_) {
-  memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
-  memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
+      allocator_(other.allocator_),
+      hash_table_(
+          other.allocator_->template Alloc<uint32_t>(other.hash_table_size_)),
+      pairs_(other.allocator_->template Alloc<typename KeyValueTrait::Pair>(
+          other.pairs_size_)),
+      hash_table_size_(other.hash_table_size_),
+      pairs_size_(other.pairs_size_),
+      next_pair_index_(other.next_pair_index_),
+      deleted_count_(other.deleted_count_) {
+  memmove(hash_table_, other.hash_table_, hash_table_size_ * sizeof(uint32_t));
+  memmove(pairs_, other.pairs_,
+          pairs_size_ * sizeof(typename KeyValueTrait::Pair));
 }
 
 template <typename KeyValueTrait, typename B, typename Allocator>
 typename KeyValueTrait::Pair*
 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Lookup(
     typename KeyValueTrait::Key key) const {
-  const typename KeyValueTrait::Value kNoValue =
-      KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
-
   uword hash = KeyValueTrait::Hash(key);
-  uword pos = Bound(hash);
-  if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
-    if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
-      return &array_[pos].kv;
+  uint32_t mask = hash_table_size_ - 1;
+  uint32_t hash_index = hash & mask;
+  uint32_t start = hash_index;
+  for (;;) {
+    uint32_t pair_index = hash_table_[hash_index];
+    if (pair_index == kEmpty) {
+      return nullptr;
     }
-
-    intptr_t next = array_[pos].next;
-    while (next != kNil) {
-      if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) {
-        return &lists_[next].kv;
+    if (pair_index != kDeleted) {
+      ASSERT(pair_index < pairs_size_);
+      if (KeyValueTrait::IsKeyEqual(pairs_[pair_index], key)) {
+        return &pairs_[pair_index];
       }
-      next = lists_[next].next;
     }
+    hash_index = (hash_index + 1) & mask;
+    // Hashtable must contain at least one empty marker.
+    ASSERT(hash_index != start);
   }
-  return NULL;
+  UNREACHABLE();
+  return nullptr;
 }
 
 template <typename KeyValueTrait, typename B, typename Allocator>
@@ -182,7 +158,7 @@
   const typename KeyValueTrait::Value kNoValue =
       KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
   typename KeyValueTrait::Pair* pair = Lookup(key);
-  return (pair == NULL) ? kNoValue : KeyValueTrait::ValueOf(*pair);
+  return (pair == nullptr) ? kNoValue : KeyValueTrait::ValueOf(*pair);
 }
 
 template <typename KeyValueTrait, typename B, typename Allocator>
@@ -190,135 +166,89 @@
 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Iterator::Next() {
   const typename KeyValueTrait::Value kNoValue =
       KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
-
-  // Return the current lists_ entry (if any), advancing list_index_.
-  if (list_index_ != kNil) {
-    intptr_t current = list_index_;
-    list_index_ = map_.lists_[current].next;
-    return &map_.lists_[current].kv;
+  while (pair_index_ < map_.next_pair_index_) {
+    if (KeyValueTrait::ValueOf(map_.pairs_[pair_index_]) != kNoValue) {
+      intptr_t old_index = pair_index_;
+      pair_index_++;
+      return &map_.pairs_[old_index];
+    }
+    pair_index_++;
   }
-
-  // When we're done with the list, we'll continue with the next array
-  // slot.
-  while ((array_index_ < map_.array_size_) &&
-         KeyValueTrait::ValueOf(map_.array_[array_index_].kv) == kNoValue) {
-    ++array_index_;
-  }
-  if (array_index_ < map_.array_size_) {
-    const intptr_t old_array_index = array_index_;
-    ++array_index_;
-    list_index_ = map_.array_[old_array_index].next;
-    return &map_.array_[old_array_index].kv;
-  }
-
   return nullptr;
 }
 
 template <typename KeyValueTrait, typename B, typename Allocator>
 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Resize(
     intptr_t new_size) {
+  ASSERT(new_size >= Size());
+
+  uint32_t old_hash_table_size = hash_table_size_;
+  // 75% load factor + at least one kEmpty slot
+  hash_table_size_ = Utils::RoundUpToPowerOfTwo(new_size * 4 / 3 + 1);
+  hash_table_ = allocator_->template Realloc<uint32_t>(
+      hash_table_, old_hash_table_size, hash_table_size_);
+  for (uint32_t i = 0; i < hash_table_size_; i++) {
+    hash_table_[i] = kEmpty;
+  }
+
+  typename KeyValueTrait::Pair* old_pairs = pairs_;
+  uint32_t old_pairs_size = pairs_size_;
+  uint32_t old_next_pair_index = next_pair_index_;
+  uint32_t old_deleted_count = deleted_count_;
+  next_pair_index_ = 0;
+  deleted_count_ = 0;
+  pairs_size_ = new_size;
+  pairs_ =
+      allocator_->template Alloc<typename KeyValueTrait::Pair>(pairs_size_);
+  for (uint32_t i = 0; i < pairs_size_; i++) {
+    pairs_[i] = typename KeyValueTrait::Pair();
+  }
+
   const typename KeyValueTrait::Value kNoValue =
       KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
-
-  ASSERT(new_size > count_);
-  // Hashing the values into the new array has no more collisions than in the
-  // old hash map, so we can use the existing lists_ array, if we are careful.
-
-  // Make sure we have at least one free element.
-  if (free_list_head_ == kNil) {
-    ResizeLists(lists_size_ << 1);
-  }
-
-  HashMapListElement* new_array =
-      allocator_->template Alloc<HashMapListElement>(new_size);
-  InitArray(new_array, new_size);
-
-  HashMapListElement* old_array = array_;
-  intptr_t old_size = array_size_;
-
-  intptr_t old_count = count_;
-  count_ = 0;
-  array_size_ = new_size;
-  array_ = new_array;
-
-  if (old_array != NULL) {
-    // Iterate over all the elements in lists, rehashing them.
-    for (intptr_t i = 0; i < old_size; ++i) {
-      if (KeyValueTrait::ValueOf(old_array[i].kv) != kNoValue) {
-        intptr_t current = old_array[i].next;
-        while (current != kNil) {
-          Insert(lists_[current].kv);
-          intptr_t next = lists_[current].next;
-          lists_[current].next = free_list_head_;
-          free_list_head_ = current;
-          current = next;
-        }
-        // Rehash the directly stored value.
-        Insert(old_array[i].kv);
-      }
+  uint32_t used = 0;
+  uint32_t deleted = 0;
+  for (uint32_t i = 0; i < old_next_pair_index; i++) {
+    if (KeyValueTrait::ValueOf(old_pairs[i]) == kNoValue) {
+      deleted++;
+    } else {
+      Insert(old_pairs[i]);
+      used++;
     }
   }
-  USE(old_count);
-  ASSERT(count_ == old_count);
-  allocator_->template Free<HashMapListElement>(old_array, old_size);
-}
-
-template <typename KeyValueTrait, typename B, typename Allocator>
-void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::ResizeLists(
-    intptr_t new_size) {
-  ASSERT(new_size > lists_size_);
-
-  HashMapListElement* new_lists =
-      allocator_->template Alloc<HashMapListElement>(new_size);
-  InitArray(new_lists, new_size);
-
-  HashMapListElement* old_lists = lists_;
-  intptr_t old_size = lists_size_;
-
-  lists_size_ = new_size;
-  lists_ = new_lists;
-
-  if (old_lists != NULL) {
-    for (intptr_t i = 0; i < old_size; i++) {
-      lists_[i] = old_lists[i];
-    }
-  }
-  for (intptr_t i = old_size; i < lists_size_; ++i) {
-    lists_[i].next = free_list_head_;
-    free_list_head_ = i;
-  }
-  allocator_->template Free<HashMapListElement>(old_lists, old_size);
+  ASSERT_EQUAL(deleted, old_deleted_count);
+  ASSERT_EQUAL(used, old_next_pair_index - old_deleted_count);
+  ASSERT_EQUAL(used, next_pair_index_);
+  allocator_->template Free<typename KeyValueTrait::Pair>(old_pairs,
+                                                          old_pairs_size);
 }
 
 template <typename KeyValueTrait, typename B, typename Allocator>
 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Insert(
     typename KeyValueTrait::Pair kv) {
-  const typename KeyValueTrait::Value kNoValue =
-      KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
-
-  ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue);
-  // TODO(dartbug.com/38018): Add assert that Lookup returns nullptr for key.
-
-  // Resizing when half of the hashtable is filled up.
-  if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
-  ASSERT(count_ < array_size_);
-  count_++;
-  uword pos = Bound(KeyValueTrait::Hash(KeyValueTrait::KeyOf(kv)));
-  if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) {
-    array_[pos].kv = kv;
-    array_[pos].next = kNil;
-  } else {
-    if (free_list_head_ == kNil) {
-      ResizeLists(lists_size_ << 1);
+  // TODO(dartbug.com/38018):
+  // ASSERT(Lookup(KeyValueTrait::KeyOf(kv)) == nullptr);
+  ASSERT(next_pair_index_ < pairs_size_);
+  uword hash = KeyValueTrait::Hash(KeyValueTrait::KeyOf(kv));
+  uint32_t mask = hash_table_size_ - 1;
+  uint32_t hash_index = hash & mask;
+  uint32_t start = hash_index;
+  for (;;) {
+    uint32_t pair_index = hash_table_[hash_index];
+    if ((pair_index == kEmpty) || (pair_index == kDeleted)) {
+      hash_table_[hash_index] = next_pair_index_;
+      pairs_[next_pair_index_] = kv;
+      next_pair_index_++;
+      break;
     }
-    intptr_t new_element_pos = free_list_head_;
-    ASSERT(new_element_pos != kNil);
-    free_list_head_ = lists_[free_list_head_].next;
-    lists_[new_element_pos].kv = kv;
-    lists_[new_element_pos].next = array_[pos].next;
-    ASSERT(array_[pos].next == kNil ||
-           KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != kNoValue);
-    array_[pos].next = new_element_pos;
+    ASSERT(pair_index < pairs_size_);
+    hash_index = (hash_index + 1) & mask;
+    // Hashtable must contain at least one empty marker.
+    ASSERT(hash_index != start);
+  }
+
+  if (next_pair_index_ == pairs_size_) {
+    Resize(Size() << 1);
   }
 }
 
@@ -339,66 +269,30 @@
 template <typename KeyValueTrait, typename B, typename Allocator>
 bool BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Remove(
     typename KeyValueTrait::Key key) {
-  const typename KeyValueTrait::Value kNoValue =
-      KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
-
-  uword pos = Bound(KeyValueTrait::Hash(key));
-
-  // Check to see if the first element in the bucket is the one we want to
-  // remove.
-  if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) return false;
-  if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
-    if (array_[pos].next == kNil) {
-      array_[pos] = HashMapListElement();
-    } else {
-      intptr_t next = array_[pos].next;
-      array_[pos] = lists_[next];
-      lists_[next] = HashMapListElement();
-      lists_[next].next = free_list_head_;
-      free_list_head_ = next;
-    }
-    count_--;
-    return true;
-  }
-
-  intptr_t current = array_[pos].next;
-
-  // If there's only the single element in the bucket and it does not match the
-  // key to be removed, just return.
-  if (current == kNil) {
-    return false;
-  }
-
-  // Check the case where the second element in the bucket is the one to be
-  // removed.
-  if (KeyValueTrait::IsKeyEqual(lists_[current].kv, key)) {
-    array_[pos].next = lists_[current].next;
-    lists_[current] = HashMapListElement();
-    lists_[current].next = free_list_head_;
-    free_list_head_ = current;
-    count_--;
-    return true;
-  }
-
-  // Finally, iterate through the rest of the bucket to see if we can find the
-  // entry that matches our key.
-  intptr_t previous = -1;
-  while (!KeyValueTrait::IsKeyEqual(lists_[current].kv, key)) {
-    previous = current;
-    current = lists_[current].next;
-
-    if (current == kNil) {
-      // Could not find entry with provided key to remove.
+  uword hash = KeyValueTrait::Hash(key);
+  uint32_t mask = hash_table_size_ - 1;
+  uint32_t hash_index = hash & mask;
+  uint32_t start = hash_index;
+  for (;;) {
+    uint32_t pair_index = hash_table_[hash_index];
+    if (pair_index == kEmpty) {
       return false;
     }
+    if (pair_index != kDeleted) {
+      ASSERT(pair_index < pairs_size_);
+      if (KeyValueTrait::IsKeyEqual(pairs_[pair_index], key)) {
+        hash_table_[hash_index] = kDeleted;
+        pairs_[pair_index] = typename KeyValueTrait::Pair();
+        deleted_count_++;
+        return true;
+      }
+    }
+    hash_index = (hash_index + 1) & mask;
+    // Hashtable must contain at least one empty marker.
+    ASSERT(hash_index != start);
   }
-
-  lists_[previous].next = lists_[current].next;
-  lists_[current] = HashMapListElement();
-  lists_[current].next = free_list_head_;
-  free_list_head_ = current;
-  count_--;
-  return true;
+  UNREACHABLE();
+  return false;
 }
 
 template <typename KeyValueTrait>
@@ -433,7 +327,7 @@
   MallocDirectChainedHashMap(
       intptr_t initial_size = MallocDirectChainedHashMap::kInitialSize)
       : BaseDirectChainedHashMap<KeyValueTrait, MallocAllocated, Malloc>(
-            NULL,
+            nullptr,
             initial_size) {}
 
   // The only use of the copy constructor seems to be in hash_map_test.cc.
@@ -502,7 +396,7 @@
   struct Pair {
     Key key;
     Value value;
-    Pair() : key(NULL), value() {}
+    Pair() : key(nullptr), value() {}
     Pair(const Key key, const Value& value) : key(key), value(value) {}
     Pair(const Pair& other) : key(other.key), value(other.value) {}
     Pair& operator=(const Pair&) = default;
@@ -645,7 +539,7 @@
   inline V Lookup(const Key& key) const {
     Pair* pair =
         DirectChainedHashMap<IntKeyRawPointerValueTrait<V> >::Lookup(key);
-    if (pair == NULL) {
+    if (pair == nullptr) {
       return V();
     } else {
       return pair->value;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 1355962..7a9fc6e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -15526,6 +15526,7 @@
 
 void CallSiteData::set_target_name(const String& value) const {
   ASSERT(!value.IsNull());
+  ASSERT(value.IsCanonical());
   untag()->set_target_name(value.ptr());
 }
 
@@ -15566,15 +15567,17 @@
 #endif
 }
 
+uword ICData::Hash() const {
+  return String::HashRawSymbol(target_name()) ^ deopt_id();
+}
+
 const char* ICData::ToCString() const {
   Zone* zone = Thread::Current()->zone();
   const String& name = String::Handle(zone, target_name());
-  const intptr_t num_args = NumArgsTested();
-  const intptr_t num_checks = NumberOfChecks();
-  const intptr_t type_args_len = TypeArgsLen();
-  return zone->PrintToString(
-      "ICData(%s num-args: %" Pd " num-checks: %" Pd " type-args-len: %" Pd ")",
-      name.ToCString(), num_args, num_checks, type_args_len);
+  return zone->PrintToString("ICData(%s num-args: %" Pd " num-checks: %" Pd
+                             " type-args-len: %" Pd ", deopt-id: %" Pd ")",
+                             name.ToCString(), NumArgsTested(),
+                             NumberOfChecks(), TypeArgsLen(), deopt_id());
 }
 
 FunctionPtr ICData::Owner() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 50d4136..b68fe85 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2436,6 +2436,8 @@
     untag()->state_bits_.UpdateBool<ReceiverCannotBeSmiBit>(value);
   }
 
+  uword Hash() const;
+
  private:
   static ICDataPtr New();
 
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 7b98530..be755ef 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3209,7 +3209,7 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(MegamorphicCache) {
-  const auto& name = String::Handle(String::New("name"));
+  const auto& name = String::Handle(Symbols::New(thread, "name"));
   const auto& args_descriptor =
       Array::Handle(ArgumentsDescriptor::NewBoxed(1, 1, Object::null_array()));
 
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 2eba0fb..14171a6 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -464,7 +464,7 @@
   const Array& ic_datas = Array::Handle(Array::New(kNumICData));
   ICData& ic_data = ICData::Handle();
   Function& owner = *CreateFunction("DummyFunction");
-  String& name = String::Handle(String::New("foo"));
+  String& name = String::Handle(Symbols::New(thread, "foo"));
   const Array& args_desc =
       Array::Handle(ArgumentsDescriptor::NewBoxed(0, 0, Object::empty_array()));
   for (intptr_t i = 0; i < kNumICData; i++) {
diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart
index 57075cb..b85de35 100644
--- a/sdk/lib/core/duration.dart
+++ b/sdk/lib/core/duration.dart
@@ -124,6 +124,10 @@
   /// Likewise, values can be negative, in which case they
   /// underflow and subtract from the next larger unit.
   ///
+  /// If the total number of microseconds cannot be represented
+  /// as an integer value, the number of microseconds might be truncated
+  /// and it might lose precision.
+  ///
   /// All arguments are 0 by default.
   const Duration(
       {int days = 0,
@@ -132,12 +136,12 @@
       int seconds = 0,
       int milliseconds = 0,
       int microseconds = 0})
-      : this._microseconds(microsecondsPerDay * days +
-            microsecondsPerHour * hours +
-            microsecondsPerMinute * minutes +
-            microsecondsPerSecond * seconds +
+      : this._microseconds(microseconds +
             microsecondsPerMillisecond * milliseconds +
-            microseconds);
+            microsecondsPerSecond * seconds +
+            microsecondsPerMinute * minutes +
+            microsecondsPerHour * hours +
+            microsecondsPerDay * days);
 
   // Fast path internal direct constructor to avoids the optional arguments and
   // [_microseconds] recomputation.
@@ -257,30 +261,35 @@
   /// d.toString();  // "1:10:00.000500"
   /// ```
   String toString() {
-    String sixDigits(int n) {
-      if (n >= 100000) return "$n";
-      if (n >= 10000) return "0$n";
-      if (n >= 1000) return "00$n";
-      if (n >= 100) return "000$n";
-      if (n >= 10) return "0000$n";
-      return "00000$n";
-    }
+    var buffer = List<String>.filled(9, "");
+    var microseconds = inMicroseconds;
 
-    String twoDigits(int n) {
-      if (n >= 10) return "$n";
-      return "0$n";
-    }
+    var hours = microseconds ~/ microsecondsPerHour;
+    microseconds = microseconds.remainder(microsecondsPerHour);
 
-    if (inMicroseconds < 0) {
-      return "-${-this}";
-    }
-    String twoDigitMinutes =
-        twoDigits(inMinutes.remainder(minutesPerHour) as int);
-    String twoDigitSeconds =
-        twoDigits(inSeconds.remainder(secondsPerMinute) as int);
-    String sixDigitUs =
-        sixDigits(inMicroseconds.remainder(microsecondsPerSecond) as int);
-    return "$inHours:$twoDigitMinutes:$twoDigitSeconds.$sixDigitUs";
+    if (microseconds < 0) microseconds = -microseconds;
+    var hoursString = hours.toString();
+    buffer
+      ..[0] = hoursString
+      ..[1] = ":";
+
+    var minutes = microseconds ~/ microsecondsPerMinute;
+    microseconds = microseconds.remainder(microsecondsPerMinute);
+
+    if (minutes < 10) buffer[2] = "0";
+    buffer
+      ..[3] = minutes.toString()
+      ..[4] = ":";
+
+    var seconds = microseconds ~/ microsecondsPerSecond;
+    microseconds = microseconds.remainder(microsecondsPerSecond);
+
+    if (seconds < 10) buffer[5] = "0";
+    buffer
+      ..[6] = seconds.toString()
+      ..[7] = "."
+      ..[8] = microseconds.toString().padLeft(6, "0");
+    return buffer.join("");
   }
 
   /// Whether this [Duration] is negative.
@@ -293,13 +302,13 @@
   /// [Duration].
   ///
   /// The returned [Duration] has the same length as this one, but is always
-  /// positive.
+  /// positive where possible.
   Duration abs() => Duration._microseconds(_duration.abs());
 
   /// Creates a new [Duration] with the opposite direction of this [Duration].
   ///
   /// The returned [Duration] has the same length as this one, but will have the
-  /// opposite sign (as reported by [isNegative]) as this one.
+  /// opposite sign (as reported by [isNegative]) as this one where possible.
   // Using subtraction helps dart2js avoid negative zeros.
   Duration operator -() => Duration._microseconds(0 - _duration);
 }
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 2079afb..0b42ab7 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -412,12 +412,12 @@
     return count;
   }
 
-  /// Returns `true` if there are no elements in this collection.
+  /// Whether this collection has no elements.
   ///
   /// May be computed by checking if `iterator.moveNext()` returns `false`.
   bool get isEmpty => !iterator.moveNext();
 
-  /// Returns true if there is at least one element in this collection.
+  /// Whether this collection has at least one element.
   ///
   /// May be computed by checking if `iterator.moveNext()` returns `true`.
   bool get isNotEmpty => !isEmpty;
diff --git a/sdk/lib/core/pattern.dart b/sdk/lib/core/pattern.dart
index 94c8980..0926b5c 100644
--- a/sdk/lib/core/pattern.dart
+++ b/sdk/lib/core/pattern.dart
@@ -19,7 +19,7 @@
   /// of the pattern in the string, initially starting from [start],
   /// and then from the end of the previous match (but always
   /// at least one position later than the *start* of the previous
-  /// match, in case the patter matches an empty substring).
+  /// match, in case the pattern matches an empty substring).
   Iterable<Match> allMatches(String string, [int start = 0]);
 
   /// Matches this pattern against the start of `string`.
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 2e3b2bd..3e2dd21 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -824,11 +824,11 @@
 // Bootstrapping native for getting the FFI native C function pointer to look
 // up the FFI resolver.
 @pragma("vm:external-name", "Ffi_GetFfiNativeResolver")
-external Pointer<NativeFunction<IntPtr Function(Handle, Handle)>>
+external Pointer<NativeFunction<IntPtr Function(Handle, Handle, IntPtr)>>
     _get_ffi_native_resolver<T extends NativeFunction>();
 
 // Resolver for FFI Native C function pointers.
 @pragma('vm:entry-point')
-final _ffi_resolver =
-    _get_ffi_native_resolver<NativeFunction<IntPtr Function(Handle, Handle)>>()
-        .asFunction<int Function(Object, Object)>();
+final _ffi_resolver = _get_ffi_native_resolver<
+        NativeFunction<IntPtr Function(Handle, Handle, IntPtr)>>()
+    .asFunction<int Function(Object, Object, int)>();
diff --git a/tests/corelib/duration_test.dart b/tests/corelib/duration_test.dart
index 842f4b0..1f8c543 100644
--- a/tests/corelib/duration_test.dart
+++ b/tests/corelib/duration_test.dart
@@ -281,6 +281,14 @@
   d = const Duration(microseconds: 1000000);
   Expect.equals("0:00:01.000000", d.toString());
 
+  // Regression test: Infinite loop prior to fix.
+  d = const Duration(microseconds: -0x8000000000000000);
+  Expect.equals("-2562047788:00:54.775808", d.toString());
+
+  d = const Duration(
+      hours: -2562047788, minutes: 0, seconds: -54, microseconds: -775808);
+  Expect.equals(-0x8000000000000000, d.inMicroseconds);
+
   d1 = const Duration(hours: 1);
   d2 = const Duration(hours: -1);
   Expect.isFalse(d1.isNegative);
diff --git a/tests/corelib_2/duration_test.dart b/tests/corelib_2/duration_test.dart
index 09a5141..1e5c5a3 100644
--- a/tests/corelib_2/duration_test.dart
+++ b/tests/corelib_2/duration_test.dart
@@ -283,6 +283,14 @@
   d = const Duration(microseconds: 1000000);
   Expect.equals("0:00:01.000000", d.toString());
 
+  // Regression test: Infinite loop prior to fix.
+  d = const Duration(microseconds: -0x8000000000000000);
+  Expect.equals("-2562047788:00:54.775808", d.toString());
+
+  d = const Duration(
+      hours: -2562047788, minutes: 0, seconds: -54, microseconds: -775808);
+  Expect.equals(-0x8000000000000000, d.inMicroseconds);
+
   d1 = const Duration(hours: 1);
   d2 = const Duration(hours: -1);
   Expect.isFalse(d1.isNegative);
diff --git a/tests/lib/html/js_interop_1_test.dart b/tests/lib/html/js_interop_1_test.dart
index 5f57dfb..cb9b6e8 100644
--- a/tests/lib/html/js_interop_1_test.dart
+++ b/tests/lib/html/js_interop_1_test.dart
@@ -27,6 +27,6 @@
     });
     injectSource("window.postMessage('hello', '*');");
 
-    await completer;
+    await completer.future;
   });
 }
diff --git a/tests/lib_2/html/js_interop_1_test.dart b/tests/lib_2/html/js_interop_1_test.dart
index 95b280e..6057d80 100644
--- a/tests/lib_2/html/js_interop_1_test.dart
+++ b/tests/lib_2/html/js_interop_1_test.dart
@@ -29,6 +29,6 @@
     });
     injectSource("window.postMessage('hello', '*');");
 
-    await completer;
+    await completer.future;
   });
 }
diff --git a/tools/VERSION b/tools/VERSION
index dded213..7a5c162 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 98
+PRERELEASE 99
 PRERELEASE_PATCH 0
\ No newline at end of file