Version 2.17.0-70.0.dev

Merge commit '872ffa85c2a5946eecc99236f9e952888a28b74f' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f525e29..5cb4c0c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -97,6 +97,14 @@
 
 [an issue]: https://github.com/dart-lang/sdk/issues/new
 
+- **Breaking Change** [#46100](https://github.com/dart-lang/sdk/issues/46100):
+  The deprecated standalone `pub` tool has been removed.
+  Its replacement is the `dart pub` command.
+  Should you find any issues, or missing features, in the replacement
+  command, kindly file [an issue][].
+
+[an issue]: https://github.com/dart-lang/pub/issues/new
+
 #### Pub
 
 - Fixed race conditions in `dart pub get`, `dart run` and `dart pub global run`.
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index f604c80..635c67b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -122,7 +122,7 @@
       for (MapEntry<String, Object?> entry in request.arguments.named.entries)
         new Symbol(entry.key): entry.value,
     }) as Macro;
-    var identifier = new MacroInstanceIdentifierImpl(instance);
+    var identifier = new MacroInstanceIdentifierImpl(instance, request.instanceId);
     _macroInstances[identifier] = instance;
     return new SerializableResponse(
         responseType: MessageType.macroInstanceIdentifier,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
index 0577fa2..7dd6004 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
@@ -216,7 +216,12 @@
   final String constructorName;
   final Arguments arguments;
 
-  InstantiateMacroRequest(this.macroClass, this.constructorName, this.arguments,
+  /// The ID to assign to the identifier, this needs to come from the requesting
+  /// side so that it is unique.
+  final int instanceId;
+
+  InstantiateMacroRequest(
+      this.macroClass, this.constructorName, this.arguments, this.instanceId,
       {required int serializationZoneId})
       : super(serializationZoneId: serializationZoneId);
 
@@ -225,6 +230,7 @@
       : macroClass = new MacroClassIdentifierImpl.deserialize(deserializer),
         constructorName = (deserializer..moveNext()).expectString(),
         arguments = new Arguments.deserialize(deserializer),
+        instanceId = (deserializer..moveNext()).expectNum(),
         super.deserialize(deserializer, serializationZoneId);
 
   @override
@@ -233,6 +239,7 @@
     macroClass.serialize(serializer);
     serializer.addString(constructorName);
     arguments.serialize(serializer);
+    serializer.addNum(instanceId);
     super.serialize(serializer);
   }
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
index eb4e5ae..08a94ed 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/response_impls.dart
@@ -25,17 +25,16 @@
 
 /// Implementation of [MacroInstanceIdentifier].
 class MacroInstanceIdentifierImpl implements MacroInstanceIdentifier {
+  /// Unique identifier for this instance, passed in from the server.
+  final int id;
+
   /// A single int where each bit indicates whether a specific macro interface
   /// is implemented by this macro.
   final int _interfaces;
 
-  static int _next = 0;
+  MacroInstanceIdentifierImpl._(this.id, this._interfaces);
 
-  final int id;
-
-  MacroInstanceIdentifierImpl._(this._interfaces) : id = _next++;
-
-  factory MacroInstanceIdentifierImpl(Macro macro) {
+  factory MacroInstanceIdentifierImpl(Macro macro, int instanceId) {
     // Build up the interfaces value, there is a bit for each declaration/phase
     // combination (as there is an interface for each).
     int interfaces = 0;
@@ -161,7 +160,7 @@
       }
     }
 
-    return new MacroInstanceIdentifierImpl._(interfaces);
+    return new MacroInstanceIdentifierImpl._(instanceId, interfaces);
   }
 
   MacroInstanceIdentifierImpl.deserialize(Deserializer deserializer)
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
index 797ffb8..2b93d2c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
@@ -137,10 +137,10 @@
           MacroClassIdentifier macroClass,
           String constructor,
           Arguments arguments) =>
-      _sendRequest(
-          new InstantiateMacroRequest(macroClass, constructor, arguments,
-              // Serialization zones are not necessary in this executor.
-              serializationZoneId: -1));
+      _sendRequest(new InstantiateMacroRequest(
+          macroClass, constructor, arguments, RemoteInstance.uniqueId,
+          // Serialization zones are not necessary in this executor.
+          serializationZoneId: -1));
 
   @override
   Future<MacroClassIdentifier> loadMacro(Uri library, String name,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
index 4c435f6..e6494f0 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
@@ -74,7 +74,7 @@
         new Symbol(entry.key): entry.value,
     }).reflectee as Macro;
     MacroInstanceIdentifierImpl identifier =
-        new MacroInstanceIdentifierImpl(instance);
+        new MacroInstanceIdentifierImpl(instance, request.instanceId);
     _macroInstances[identifier] = instance;
     return new Response(
         response: identifier,
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
index cfe6602..eeeeb45 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
@@ -429,7 +429,7 @@
           String constructor,
           Arguments arguments) =>
       _sendRequest((zoneId) => new InstantiateMacroRequest(
-          macroClass, constructor, arguments,
+          macroClass, constructor, arguments, RemoteInstance.uniqueId,
           serializationZoneId: zoneId));
 
   /// These calls are handled by the higher level executor.
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index 0a6ab6c..6573bbc 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -734,6 +734,9 @@
       : super(type, offset, precedingComment);
 
   @override
+  Token? beforeSynthetic;
+
+  @override
   Token copy() =>
       new SyntheticBeginToken(type, offset, copyComments(precedingComments));
 
@@ -755,6 +758,9 @@
   SyntheticKeywordToken(Keyword keyword, int offset) : super(keyword, offset);
 
   @override
+  Token? beforeSynthetic;
+
+  @override
   int get length => 0;
 
   @override
diff --git a/pkg/_fe_analyzer_shared/test/macros/executor_shared/response_impls_test.dart b/pkg/_fe_analyzer_shared/test/macros/executor_shared/response_impls_test.dart
index da0c02e..88ef6fb 100644
--- a/pkg/_fe_analyzer_shared/test/macros/executor_shared/response_impls_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/executor_shared/response_impls_test.dart
@@ -2,6 +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:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
 import 'package:test/fake.dart';
 import 'package:test/test.dart';
 
@@ -67,43 +68,52 @@
 final Map<DeclarationKind, Map<Phase, MacroInstanceIdentifierImpl>>
     instancesByKindAndPhase = {
   DeclarationKind.clazz: {
-    Phase.types: MacroInstanceIdentifierImpl(FakeClassTypesMacro()),
-    Phase.declarations:
-        MacroInstanceIdentifierImpl(FakeClassDeclarationsMacro()),
-    Phase.definitions: MacroInstanceIdentifierImpl(FakeClassDefinitionMacro()),
+    Phase.types: MacroInstanceIdentifierImpl(
+        FakeClassTypesMacro(), RemoteInstance.uniqueId),
+    Phase.declarations: MacroInstanceIdentifierImpl(
+        FakeClassDeclarationsMacro(), RemoteInstance.uniqueId),
+    Phase.definitions: MacroInstanceIdentifierImpl(
+        FakeClassDefinitionMacro(), RemoteInstance.uniqueId),
   },
   DeclarationKind.constructor: {
-    Phase.types: MacroInstanceIdentifierImpl(FakeConstructorTypesMacro()),
-    Phase.declarations:
-        MacroInstanceIdentifierImpl(FakeConstructorDeclarationsMacro()),
-    Phase.definitions:
-        MacroInstanceIdentifierImpl(FakeConstructorDefinitionMacro()),
+    Phase.types: MacroInstanceIdentifierImpl(
+        FakeConstructorTypesMacro(), RemoteInstance.uniqueId),
+    Phase.declarations: MacroInstanceIdentifierImpl(
+        FakeConstructorDeclarationsMacro(), RemoteInstance.uniqueId),
+    Phase.definitions: MacroInstanceIdentifierImpl(
+        FakeConstructorDefinitionMacro(), RemoteInstance.uniqueId),
   },
   DeclarationKind.field: {
-    Phase.types: MacroInstanceIdentifierImpl(FakeFieldTypesMacro()),
-    Phase.declarations:
-        MacroInstanceIdentifierImpl(FakeFieldDeclarationsMacro()),
-    Phase.definitions: MacroInstanceIdentifierImpl(FakeFieldDefinitionMacro()),
+    Phase.types: MacroInstanceIdentifierImpl(
+        FakeFieldTypesMacro(), RemoteInstance.uniqueId),
+    Phase.declarations: MacroInstanceIdentifierImpl(
+        FakeFieldDeclarationsMacro(), RemoteInstance.uniqueId),
+    Phase.definitions: MacroInstanceIdentifierImpl(
+        FakeFieldDefinitionMacro(), RemoteInstance.uniqueId),
   },
   DeclarationKind.function: {
-    Phase.types: MacroInstanceIdentifierImpl(FakeFunctionTypesMacro()),
-    Phase.declarations:
-        MacroInstanceIdentifierImpl(FakeFunctionDeclarationsMacro()),
-    Phase.definitions:
-        MacroInstanceIdentifierImpl(FakeFunctionDefinitionMacro()),
+    Phase.types: MacroInstanceIdentifierImpl(
+        FakeFunctionTypesMacro(), RemoteInstance.uniqueId),
+    Phase.declarations: MacroInstanceIdentifierImpl(
+        FakeFunctionDeclarationsMacro(), RemoteInstance.uniqueId),
+    Phase.definitions: MacroInstanceIdentifierImpl(
+        FakeFunctionDefinitionMacro(), RemoteInstance.uniqueId),
   },
   DeclarationKind.method: {
-    Phase.types: MacroInstanceIdentifierImpl(FakeMethodTypesMacro()),
-    Phase.declarations:
-        MacroInstanceIdentifierImpl(FakeMethodDeclarationsMacro()),
-    Phase.definitions: MacroInstanceIdentifierImpl(FakeMethodDefinitionMacro()),
+    Phase.types: MacroInstanceIdentifierImpl(
+        FakeMethodTypesMacro(), RemoteInstance.uniqueId),
+    Phase.declarations: MacroInstanceIdentifierImpl(
+        FakeMethodDeclarationsMacro(), RemoteInstance.uniqueId),
+    Phase.definitions: MacroInstanceIdentifierImpl(
+        FakeMethodDefinitionMacro(), RemoteInstance.uniqueId),
   },
   DeclarationKind.variable: {
-    Phase.types: MacroInstanceIdentifierImpl(FakeVariableTypesMacro()),
-    Phase.declarations:
-        MacroInstanceIdentifierImpl(FakeVariableDeclarationsMacro()),
-    Phase.definitions:
-        MacroInstanceIdentifierImpl(FakeVariableDefinitionMacro()),
+    Phase.types: MacroInstanceIdentifierImpl(
+        FakeVariableTypesMacro(), RemoteInstance.uniqueId),
+    Phase.declarations: MacroInstanceIdentifierImpl(
+        FakeVariableDeclarationsMacro(), RemoteInstance.uniqueId),
+    Phase.definitions: MacroInstanceIdentifierImpl(
+        FakeVariableDefinitionMacro(), RemoteInstance.uniqueId),
   },
 };
 
diff --git a/pkg/analyzer/test/generated/error_parser_test.dart b/pkg/analyzer/test/generated/error_parser_test.dart
index 41a03fc..7073755 100644
--- a/pkg/analyzer/test/generated/error_parser_test.dart
+++ b/pkg/analyzer/test/generated/error_parser_test.dart
@@ -1683,9 +1683,9 @@
 
   void test_invalidTypedef() {
     parseCompilationUnit("typedef var Function(var arg);", errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 7),
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
       expectedError(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, 8, 3),
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 3),
       expectedError(ParserErrorCode.VAR_RETURN_TYPE, 8, 3),
       expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 29, 1),
     ]);
diff --git a/pkg/front_end/lib/src/api_prototype/expression_compilation_tools.dart b/pkg/front_end/lib/src/api_prototype/expression_compilation_tools.dart
new file mode 100644
index 0000000..f078627
--- /dev/null
+++ b/pkg/front_end/lib/src/api_prototype/expression_compilation_tools.dart
@@ -0,0 +1,213 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart'
+    show isLegalIdentifier;
+
+import 'package:front_end/src/api_prototype/lowering_predicates.dart'
+    show isExtensionThisName;
+
+import 'package:kernel/ast.dart'
+    show
+        Class,
+        DartType,
+        DynamicType,
+        InterfaceType,
+        Library,
+        Nullability,
+        TypeParameter;
+
+import 'package:kernel/library_index.dart' show LibraryIndex;
+
+Map<String, DartType>? createDefinitionsWithTypes(
+    Iterable<Library>? knownLibraries,
+    List<String> definitionTypes,
+    List<String> definitions) {
+  if (knownLibraries == null) {
+    return null;
+  }
+
+  List<ParsedType> definitionTypesParsed =
+      parseDefinitionTypes(definitionTypes);
+  if (definitionTypesParsed.length != definitions.length) {
+    return null;
+  }
+
+  Set<String> libraryUris = collectParsedTypeUris(definitionTypesParsed);
+  LibraryIndex libraryIndex =
+      new LibraryIndex.fromLibraries(knownLibraries, libraryUris);
+
+  Map<String, DartType> completeDefinitions = {};
+  for (int i = 0; i < definitions.length; i++) {
+    String name = definitions[i];
+    if (isLegalIdentifier(name) || (i == 0 && isExtensionThisName(name))) {
+      ParsedType type = definitionTypesParsed[i];
+      DartType dartType = type.createDartType(libraryIndex);
+      completeDefinitions[name] = dartType;
+    }
+  }
+  return completeDefinitions;
+}
+
+List<TypeParameter>? createTypeParametersWithBounds(
+    Iterable<Library>? knownLibraries,
+    List<String> typeBounds,
+    List<String> typeDefaults,
+    List<String> typeDefinitions) {
+  if (knownLibraries == null) {
+    return null;
+  }
+
+  List<ParsedType> typeBoundsParsed = parseDefinitionTypes(typeBounds);
+  if (typeBoundsParsed.length != typeDefinitions.length) {
+    return null;
+  }
+  List<ParsedType> typeDefaultsParsed = parseDefinitionTypes(typeDefaults);
+  if (typeDefaultsParsed.length != typeDefinitions.length) {
+    return null;
+  }
+
+  Set<String> libraryUris = collectParsedTypeUris(typeBoundsParsed)
+    ..addAll(collectParsedTypeUris(typeDefaultsParsed));
+  LibraryIndex libraryIndex =
+      new LibraryIndex.fromLibraries(knownLibraries, libraryUris);
+
+  List<TypeParameter> typeParameters = [];
+  for (int i = 0; i < typeDefinitions.length; i++) {
+    String name = typeDefinitions[i];
+    if (!isLegalIdentifier(name)) continue;
+    ParsedType bound = typeBoundsParsed[i];
+    DartType dartTypeBound = bound.createDartType(libraryIndex);
+    ParsedType defaultType = typeDefaultsParsed[i];
+    DartType dartTypeDefaultType = defaultType.createDartType(libraryIndex);
+    typeParameters
+        .add(new TypeParameter(name, dartTypeBound, dartTypeDefaultType));
+  }
+  return typeParameters;
+}
+
+List<ParsedType> parseDefinitionTypes(List<String> definitionTypes) {
+  List<ParsedType> result = [];
+  int i = 0;
+  List<ParsedType> argumentReceivers = [];
+  while (i < definitionTypes.length) {
+    String uriOrNullString = definitionTypes[i];
+    if (uriOrNullString == "null") {
+      if (argumentReceivers.isEmpty) {
+        result.add(new ParsedType.nullType());
+      } else {
+        argumentReceivers
+            .removeLast()
+            .arguments!
+            .add(new ParsedType.nullType());
+      }
+      i++;
+      continue;
+    } else {
+      // We expect at least 4 elements: Uri, class name, nullability,
+      // number of type arguments.
+      if (i + 4 > definitionTypes.length) throw "invalid input";
+      String className = definitionTypes[i + 1];
+      int nullability = int.parse(definitionTypes[i + 2]);
+      int typeArgumentsCount = int.parse(definitionTypes[i + 3]);
+      ParsedType type = new ParsedType(uriOrNullString, className, nullability);
+      if (argumentReceivers.isEmpty) {
+        result.add(type);
+      } else {
+        argumentReceivers.removeLast().arguments!.add(type);
+      }
+      for (int j = 0; j < typeArgumentsCount; j++) {
+        argumentReceivers.add(type);
+      }
+      i += 4;
+    }
+  }
+  if (argumentReceivers.isNotEmpty) {
+    throw "Nesting error on input $definitionTypes";
+  }
+  return result;
+}
+
+class ParsedType {
+  final String? uri;
+  final String? className;
+  final int? nullability;
+  final List<ParsedType>? arguments;
+
+  bool get isNullType => uri == null;
+
+  ParsedType(this.uri, this.className, this.nullability) : arguments = [];
+
+  ParsedType.nullType()
+      : uri = null,
+        className = null,
+        nullability = null,
+        arguments = null;
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! ParsedType) return false;
+    if (uri != other.uri) return false;
+    if (className != other.className) return false;
+    if (nullability != other.nullability) return false;
+    if (arguments?.length != other.arguments?.length) return false;
+    if (arguments != null) {
+      for (int i = 0; i < arguments!.length; i++) {
+        if (arguments![i] != other.arguments![i]) return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  int get hashCode {
+    if (isNullType) return 0;
+    int hash = 0x3fffffff & uri.hashCode;
+    hash = 0x3fffffff & (hash * 31 + (hash ^ className.hashCode));
+    hash = 0x3fffffff & (hash * 31 + (hash ^ nullability.hashCode));
+    for (ParsedType argument in arguments!) {
+      hash = 0x3fffffff & (hash * 31 + (hash ^ argument.hashCode));
+    }
+    return hash;
+  }
+
+  @override
+  String toString() {
+    if (isNullType) return "null-type";
+    return "$uri[$className] ($nullability) <$arguments>";
+  }
+
+  DartType createDartType(LibraryIndex libraryIndex) {
+    if (isNullType) return new DynamicType();
+    Class? classNode = libraryIndex.tryGetClass(uri!, className!);
+    if (classNode == null) return new DynamicType();
+
+    return new InterfaceType(
+        classNode,
+        _getDartNullability(),
+        arguments
+            ?.map((e) => e.createDartType(libraryIndex))
+            .toList(growable: false));
+  }
+
+  Nullability _getDartNullability() {
+    if (isNullType) throw "No nullability on the null type";
+    if (nullability == 0) return Nullability.nullable;
+    if (nullability == 1) return Nullability.nonNullable;
+    if (nullability == 2) return Nullability.legacy;
+    throw "Unknown nullability";
+  }
+}
+
+Set<String> collectParsedTypeUris(List<ParsedType> parsedTypes) {
+  Set<String> result = {};
+  List<ParsedType> workList = new List.from(parsedTypes);
+  while (workList.isNotEmpty) {
+    ParsedType type = workList.removeLast();
+    if (type.isNullType) continue;
+    result.add(type.uri!);
+    workList.addAll(type.arguments!);
+  }
+  return result;
+}
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index b915847..9190ebc 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -18,6 +18,9 @@
 export '../api_prototype/experimental_flags.dart'
     show defaultExperimentalFlags, ExperimentalFlag;
 
+export '../api_prototype/expression_compilation_tools.dart'
+    show createDefinitionsWithTypes, createTypeParametersWithBounds;
+
 export '../api_prototype/file_system.dart'
     show FileSystem, FileSystemEntity, FileSystemException;
 
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.expect
index 0b3a014..742472b 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.expect
@@ -6,11 +6,9 @@
 
 WARNING: Reporting at eof --- see below for details.
 
-parser/error_recovery/issue_38415.crash:1:15: Expected ';' after this.
+parser/error_recovery/issue_38415.crash:1:14: Expected ';' after this.
 f() { m(T<R(<Z
-              ^...
-
-WARNING: Reporting at eof --- see below for details.
+             ^
 
 parser/error_recovery/issue_38415.crash:1:12: Can't find ')' to match '('.
 f() { m(T<R(<Z
@@ -64,8 +62,7 @@
           endBinaryExpression(<)
         endArguments(1, (, ))
         handleSend(m, })
-        handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], , )
-        // WARNING: Reporting at eof for .
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], Z, Z)
         handleExpressionStatement(;)
       endBlockFunctionBody(1, {, })
     endTopLevelMethod(f, null, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.intertwined.expect
index 6f0eacd..7e5afad 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_38415.crash_dart.intertwined.expect
@@ -102,9 +102,8 @@
                                     listener: endArguments(1, (, ))
                               listener: handleSend(m, })
                   ensureSemicolon())
-                    reportRecoverableError([, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
-                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], , )
-                      listener: // WARNING: Reporting at eof for .
+                    reportRecoverableError(Z, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], Z, Z)
                     rewriter()
                   listener: handleExpressionStatement(;)
           notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39058.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39058.crash_dart.intertwined.expect
index c386263..4bbd143 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39058.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39058.crash_dart.intertwined.expect
@@ -41,7 +41,7 @@
                                   rewriter()
                                 listener: handleLiteralList(0, [, null, ])
                     ensureSemicolon(])
-                      reportRecoverableError([, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      reportRecoverableError((, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
                       rewriter()
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39058_prime.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39058_prime.crash_dart.intertwined.expect
index caab7bd..4ed5364 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39058_prime.crash_dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39058_prime.crash_dart.intertwined.expect
@@ -41,7 +41,7 @@
                                   rewriter()
                                 listener: handleLiteralList(0, [, null, ])
                     ensureSemicolon(])
-                      reportRecoverableError([, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                      reportRecoverableError(>, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
                       rewriter()
                     listener: handleExpressionStatement(;)
           notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.expect
index f1b7c51..de5b119 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.expect
@@ -12,9 +12,9 @@
 }
 ^
 
-parser/error_recovery/issue_39060:3:1: Expected ';' after this.
-}
-^
+parser/error_recovery/issue_39060:2:9: Expected ';' after this.
+  {s A<}>
+        ^
 
 beginCompilationUnit(main)
   beginMetadataStar(main)
@@ -49,7 +49,7 @@
           endTypeArguments(1, <, >)
           handleRecoverableError(Message[ExpectedButGot, Expected '[' before this., null, {string: [}], }, })
           handleLiteralList(0, [, null, ])
-          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], >, >)
           handleExpressionStatement(;)
         endBlock(2, {, }, BlockKind(statement))
       endBlockFunctionBody(1, {, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.intertwined.expect
index c6ddd9b..bb5e98d 100644
--- a/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_39060.dart.intertwined.expect
@@ -85,8 +85,8 @@
                                         rewriter()
                                       listener: handleLiteralList(0, [, null, ])
                           ensureSemicolon(])
-                            reportRecoverableError([, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
-                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                            reportRecoverableError(>, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                              listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], >, >)
                             rewriter()
                           listener: handleExpressionStatement(;)
                 notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
index a281a5c..34b8bbc 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.expect
@@ -112,9 +112,9 @@
   }
   ^
 
-parser/error_recovery/keyword_named_class_methods:75:3: Expected ';' after this.
-  }
-  ^
+parser/error_recovery/keyword_named_class_methods:74:23: Expected ';' after this.
+    return do(x-1) + 1;
+                      ^
 
 parser/error_recovery/keyword_named_class_methods:82:7: 'else' can't be used as an identifier because it's a keyword.
   int else(int x) {
@@ -1394,7 +1394,7 @@
                 handleNoArguments())
                 handleSend(, ))
                 handleParenthesizedCondition(()
-                handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
               endDoWhileStatement(do, while, ;)
             endBlockFunctionBody(3, {, })
           endClassMethod(null, int, (, null, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
index 75b6cd7..9e74712 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_class_methods.dart.intertwined.expect
@@ -2325,8 +2325,8 @@
                             ensureCloseParen(, ()
                           listener: handleParenthesizedCondition(()
                         ensureSemicolon())
-                          reportRecoverableError((, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
-                            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                          reportRecoverableError(;, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
                           rewriter()
                         listener: endDoWhileStatement(do, while, ;)
                   notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect
index 85b9f18..8734745 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.expect
@@ -112,9 +112,9 @@
 }
 ^
 
-parser/error_recovery/keyword_named_top_level_methods:74:1: Expected ';' after this.
-}
-^
+parser/error_recovery/keyword_named_top_level_methods:73:21: Expected ';' after this.
+  return do(x-1) + 1;
+                    ^
 
 parser/error_recovery/keyword_named_top_level_methods:81:5: 'else' can't be used as an identifier because it's a keyword.
 int else(int x) {
@@ -1359,7 +1359,7 @@
           handleNoArguments())
           handleSend(, ))
           handleParenthesizedCondition(()
-          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+          handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
         endDoWhileStatement(do, while, ;)
       endBlockFunctionBody(3, {, })
     endTopLevelMethod(int, null, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect
index bad4dea..385ad93 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_top_level_methods.dart.intertwined.expect
@@ -2241,8 +2241,8 @@
                     ensureCloseParen(, ()
                   listener: handleParenthesizedCondition(()
                 ensureSemicolon())
-                  reportRecoverableError((, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
-                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], }, })
+                  reportRecoverableError(;, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+                    listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], ;, ;)
                   rewriter()
                 listener: endDoWhileStatement(do, while, ;)
           notEofOrValue(}, })
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.expect
index 1f1f6e6..f39ac71 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.expect
@@ -436,9 +436,9 @@
 typedef void = void Function();
              ^
 
-parser/error_recovery/keyword_named_typedefs:132:14: Expected ';' after this.
+parser/error_recovery/keyword_named_typedefs:132:9: Expected ';' after this.
 typedef void = void Function();
-             ^
+        ^^^^
 
 parser/error_recovery/keyword_named_typedefs:132:14: Expected a declaration, but got '='.
 typedef void = void Function();
@@ -2219,7 +2219,7 @@
       handleRecoverableError(MissingTypedefParameters, =, =)
       beginFormalParameters((, MemberKind.FunctionTypeAlias)
       endFormalParameters(0, (, ), MemberKind.FunctionTypeAlias)
-      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], =, =)
+      handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
     endTypedef(typedef, null, ;)
   endTopLevelDeclaration(=)
   beginMetadataStar(=)
diff --git a/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.intertwined.expect
index 93da896..68d9dd8 100644
--- a/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/error_recovery/keyword_named_typedefs.dart.intertwined.expect
@@ -3057,8 +3057,8 @@
             listener: beginFormalParameters((, MemberKind.FunctionTypeAlias)
             listener: endFormalParameters(0, (, ), MemberKind.FunctionTypeAlias)
         ensureSemicolon())
-          reportRecoverableError((, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
-            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], =, =)
+          reportRecoverableError(void, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], void, void)
           rewriter()
         listener: endTypedef(typedef, null, ;)
   listener: endTopLevelDeclaration(=)
diff --git a/pkg/front_end/test/expression_compilation_tools_test.dart b/pkg/front_end/test/expression_compilation_tools_test.dart
new file mode 100644
index 0000000..9e12fb4
--- /dev/null
+++ b/pkg/front_end/test/expression_compilation_tools_test.dart
@@ -0,0 +1,135 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/minitest.dart';
+
+import 'package:front_end/src/api_prototype/expression_compilation_tools.dart';
+
+void main() {
+  // null value.
+  expect(parseDefinitionTypes(["null"]), [new ParsedType.nullType()]);
+
+  // String, kNonNullable
+  expect(
+      parseDefinitionTypes([
+        "dart:core",
+        "_OneByteString",
+        "1",
+        "0",
+      ]),
+      [new ParsedType("dart:core", "_OneByteString", 1)]);
+
+  // List<something it can't represent which thus becomes an explicit
+  // dynamic/null>, kNonNullable.
+  expect(parseDefinitionTypes(["dart:core", "List", "1", "1", "null"]), [
+    new ParsedType("dart:core", "List", 1)
+      ..arguments!.add(new ParsedType.nullType())
+  ]);
+
+  // List<int>, kNonNullable
+  expect(
+      parseDefinitionTypes([
+        "dart:core",
+        "_GrowableList",
+        "1",
+        "1",
+        "dart:core",
+        "int",
+        "1",
+        "0",
+      ]),
+      [
+        new ParsedType("dart:core", "_GrowableList", 1)
+          ..arguments!.add(new ParsedType("dart:core", "int", 1))
+      ]);
+
+  // Map<int, int>, kNonNullable
+  expect(
+      parseDefinitionTypes([
+        "dart:core",
+        "Map",
+        "1",
+        "2",
+        "dart:core",
+        "int",
+        "1",
+        "0",
+        "dart:core",
+        "int",
+        "1",
+        "0",
+      ]),
+      [
+        new ParsedType("dart:core", "Map", 1)
+          ..arguments!.add(new ParsedType("dart:core", "int", 1))
+          ..arguments!.add(new ParsedType("dart:core", "int", 1))
+      ]);
+
+  // [0] = String
+  // [1] = int
+  // [2] = List<String>
+  // [3] = Bar
+  // [4] = null
+  // [5] = HashMap<Map<int, List<int>>, List<String>>
+  expect(
+      parseDefinitionTypes([
+        // String, kNonNullable, no arguments
+        "dart:core", "_OneByteString", "1", "0",
+        // Int, kNonNullable, no arguments
+        "dart:core", "_Smi", "1", "0",
+        // List, kNonNullable, 1 argument
+        "dart:core", "_GrowableList", "1", "1",
+        //  -> String, kNonNullable (i.e. the above is List<String>)
+        /**/ "dart:core", "String", "1", "0",
+        // "Bar", kNonNullable, no arguments
+        "file://wherever/t.dart", "Bar", "1", "0",
+        // null value
+        "null",
+        // HashMap, kNonNullable, 2 arguments
+        "dart:collection", "_InternalLinkedHashMap", "1", "2",
+        //   -> Map, kNonNullable, 2 arguments
+        /**/ "dart:core", "Map", "1", "2",
+        //   -> -> int, kNonNullable, no arguments
+        /*/**/*/ "dart:core", "int", "1", "0",
+        //   -> -> List, kNonNullable, 1 argument
+        /*/**/*/ "dart:core", "List", "1", "1",
+        //   -> -> -> int, kNonNullable, no arguments
+        /*/*/**/*/*/ "dart:core", "int", "1", "0",
+        //   -> List, kNonNullable, 1 argument
+        "dart:core", "List", "1", "1",
+        //   -> -> String, kNonNullable, no arguments
+        "dart:core", "String", "1", "0"
+      ]),
+      <ParsedType>[
+        // String
+        new ParsedType("dart:core", "_OneByteString", 1),
+        // int
+        new ParsedType("dart:core", "_Smi", 1),
+        // List<String>
+        new ParsedType("dart:core", "_GrowableList", 1)
+          ..arguments!.addAll([
+            new ParsedType("dart:core", "String", 1),
+          ]),
+        // Bar
+        new ParsedType("file://wherever/t.dart", "Bar", 1),
+        // null value
+        new ParsedType.nullType(),
+        // HashMap<Map<int, List<int>>, List<String>>
+        new ParsedType("dart:collection", "_InternalLinkedHashMap", 1)
+          ..arguments!.addAll([
+            new ParsedType("dart:core", "Map", 1)
+              ..arguments!.addAll([
+                new ParsedType("dart:core", "int", 1),
+                new ParsedType("dart:core", "List", 1)
+                  ..arguments!.addAll([
+                    new ParsedType("dart:core", "int", 1),
+                  ]),
+              ]),
+            new ParsedType("dart:core", "List", 1)
+              ..arguments!.addAll([
+                new ParsedType("dart:core", "String", 1),
+              ]),
+          ]),
+      ]);
+}
diff --git a/pkg/front_end/test/fasta/expression_suite.dart b/pkg/front_end/test/fasta/expression_suite.dart
index 03eeb59..520e7e1 100644
--- a/pkg/front_end/test/fasta/expression_suite.dart
+++ b/pkg/front_end/test/fasta/expression_suite.dart
@@ -16,6 +16,12 @@
     show CompilerOptions, DiagnosticMessage;
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
 
+import 'package:front_end/src/api_prototype/expression_compilation_tools.dart'
+    show createDefinitionsWithTypes, createTypeParametersWithBounds;
+
+import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart'
+    show IncrementalCompilerResult;
+
 import "package:front_end/src/api_prototype/memory_file_system.dart"
     show MemoryFileSystem;
 
@@ -34,7 +40,7 @@
     show IncrementalCompiler;
 
 import "package:kernel/ast.dart"
-    show Procedure, Component, DynamicType, DartType, TypeParameter;
+    show Component, DartType, DynamicType, Procedure, TypeParameter;
 
 import 'package:kernel/target/targets.dart' show TargetFlags;
 
@@ -132,8 +138,14 @@
 
   final List<String> definitions;
 
+  final List<String> definitionTypes;
+
   final List<String> typeDefinitions;
 
+  final List<String> typeBounds;
+
+  final List<String> typeDefaults;
+
   final bool isStaticMethod;
 
   final Uri? library;
@@ -151,7 +163,10 @@
       this.entryPoint,
       this.import,
       this.definitions,
+      this.definitionTypes,
       this.typeDefinitions,
+      this.typeBounds,
+      this.typeDefaults,
       this.isStaticMethod,
       this.library,
       this.className,
@@ -164,7 +179,10 @@
         "$entryPoint, "
         "$import, "
         "$definitions, "
+        "$definitionTypes, "
         "$typeDefinitions,"
+        "$typeBounds,"
+        "$typeDefaults,"
         "$library, "
         "$className, "
         "static = $isStaticMethod)";
@@ -259,7 +277,10 @@
     Uri? entryPoint;
     Uri? import;
     List<String> definitions = <String>[];
+    List<String> definitionTypes = <String>[];
     List<String> typeDefinitions = <String>[];
+    List<String> typeBounds = <String>[];
+    List<String> typeDefaults = <String>[];
     bool isStaticMethod = false;
     Uri? library;
     String? className;
@@ -289,9 +310,16 @@
           methodName = value as String;
         } else if (key == "definitions") {
           definitions = (value as YamlList).map((x) => x as String).toList();
+        } else if (key == "definition_types") {
+          definitionTypes =
+              (value as YamlList).map((x) => x as String).toList();
         } else if (key == "type_definitions") {
           typeDefinitions =
               (value as YamlList).map((x) => x as String).toList();
+        } else if (key == "type_bounds") {
+          typeBounds = (value as YamlList).map((x) => x as String).toList();
+        } else if (key == "type_defaults") {
+          typeDefaults = (value as YamlList).map((x) => x as String).toList();
         } else if (key == "static") {
           isStaticMethod = value;
         } else if (key == "expression") {
@@ -303,7 +331,10 @@
           entryPoint,
           import,
           definitions,
+          definitionTypes,
           typeDefinitions,
+          typeBounds,
+          typeDefaults,
           isStaticMethod,
           library,
           className,
@@ -328,15 +359,29 @@
   // Compile [test.expression], update [test.errors] with results.
   // As a side effect - verify that generated procedure can be serialized.
   Future<void> compileExpression(TestCase test, IncrementalCompiler compiler,
-      Component component, Context context) async {
-    Map<String, DartType> definitions = {};
-    for (String name in test.definitions) {
-      definitions[name] = new DynamicType();
+      IncrementalCompilerResult sourceCompilerResult, Context context) async {
+    Map<String, DartType>? definitions = createDefinitionsWithTypes(
+        sourceCompilerResult.classHierarchy?.knownLibraries,
+        test.definitionTypes,
+        test.definitions);
+
+    if (definitions == null) {
+      definitions = {};
+      for (String name in test.definitions) {
+        definitions[name] = new DynamicType();
+      }
     }
-    List<TypeParameter> typeParams = [];
-    for (String name in test.typeDefinitions) {
-      typeParams
-          .add(new TypeParameter(name, new DynamicType(), new DynamicType()));
+    List<TypeParameter>? typeParams = createTypeParametersWithBounds(
+        sourceCompilerResult.classHierarchy?.knownLibraries,
+        test.typeBounds,
+        test.typeDefaults,
+        test.typeDefinitions);
+    if (typeParams == null) {
+      typeParams = [];
+      for (String name in test.typeDefinitions) {
+        typeParams
+            .add(new TypeParameter(name, new DynamicType(), new DynamicType()));
+      }
     }
 
     Procedure? compiledProcedure = await compiler.compileExpression(
@@ -353,7 +398,7 @@
     test.results.add(new CompilationResult(compiledProcedure, errors));
     if (compiledProcedure != null) {
       // Confirm we can serialize generated procedure.
-      component.computeCanonicalNames();
+      sourceCompilerResult.component.computeCanonicalNames();
       List<int> list = serializeProcedure(compiledProcedure);
       assert(list.length > 0);
     }
@@ -371,8 +416,9 @@
             await new File.fromUri(test.import!).readAsBytes());
       }
 
-      var sourceCompiler = new IncrementalCompiler(context.compilerContext);
-      var sourceCompilerResult =
+      IncrementalCompiler sourceCompiler =
+          new IncrementalCompiler(context.compilerContext);
+      IncrementalCompilerResult sourceCompilerResult =
           await sourceCompiler.computeDelta(entryPoints: [test.entryPoint!]);
       Component component = sourceCompilerResult.component;
       var errors = context.takeErrors();
@@ -387,11 +433,12 @@
           path: test.entryPoint!.path + ".dill");
       Uint8List dillData = await serializeComponent(component);
       context.fileSystem.entityForUri(dillFileUri).writeAsBytesSync(dillData);
-      await compileExpression(test, sourceCompiler, component, context);
+      await compileExpression(
+          test, sourceCompiler, sourceCompilerResult, context);
 
-      var dillCompiler =
+      IncrementalCompiler dillCompiler =
           new IncrementalCompiler(context.compilerContext, dillFileUri);
-      var dillCompilerResult =
+      IncrementalCompilerResult dillCompilerResult =
           await dillCompiler.computeDelta(entryPoints: [test.entryPoint!]);
       component = dillCompilerResult.component;
       component.computeCanonicalNames();
@@ -400,7 +447,7 @@
       // Since it compiled successfully from source, the bootstrap-from-Dill
       // should also succeed without errors.
       assert(errors.isEmpty);
-      await compileExpression(test, dillCompiler, component, context);
+      await compileExpression(test, dillCompiler, dillCompilerResult, context);
     }
     return new Result.pass(tests);
   }
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 19431ef..ca447e7 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -1035,6 +1035,7 @@
 repo
 repositories
 repurposed
+requesting
 requests
 requirement
 res
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index bea0c4d..33568c9 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -398,6 +398,7 @@
 minimize
 minimizer
 minimizing
+minitest
 minst
 mintty
 minutes
diff --git a/pkg/front_end/testcases/expression/evaluate_extension_method.expression.yaml b/pkg/front_end/testcases/expression/evaluate_extension_method.expression.yaml
new file mode 100644
index 0000000..ad1a058
--- /dev/null
+++ b/pkg/front_end/testcases/expression/evaluate_extension_method.expression.yaml
@@ -0,0 +1,17 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+# List<String>
+definition_types: ["dart:core", "List", "1", "1", "dart:core", "String", "1", "0"]
+type_definitions: [""]
+type_bounds: []
+type_defaults: []
+position: "main.dart"
+method: "hasList"
+# x is List<String> with entries, so x.first is String, String has extension
+# with method getFortyTwo.
+expression: |
+  x.first.getFortyTwo()
diff --git a/pkg/front_end/testcases/expression/evaluate_extension_method.expression.yaml.expect b/pkg/front_end/testcases/expression/evaluate_extension_method.expression.yaml.expect
new file mode 100644
index 0000000..8545fba
--- /dev/null
+++ b/pkg/front_end/testcases/expression/evaluate_extension_method.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr< extends dynamic>(dart.core::List<dart.core::String> x) → dynamic
+  return main::Foo|getFortyTwo(x.{dart.core::Iterable::first}{dart.core::String*});
diff --git a/pkg/front_end/testcases/expression/evaluate_fold_on_list.expression.yaml b/pkg/front_end/testcases/expression/evaluate_fold_on_list.expression.yaml
new file mode 100644
index 0000000..e43e163
--- /dev/null
+++ b/pkg/front_end/testcases/expression/evaluate_fold_on_list.expression.yaml
@@ -0,0 +1,16 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+# List<String>, int
+definition_types: ["dart:core", "List", "1", "1", "dart:core", "String", "1", "0", "dart:core", "int", "1", "0"]
+type_definitions: []
+type_bounds: []
+type_defaults: []
+position: "main.dart"
+method: "hasList"
+# Because x has a type (List<String>) x.fold knows that element is a String.
+expression: |
+  x.fold<int>(0, (previousValue, element) => previousValue + element.length)
diff --git a/pkg/front_end/testcases/expression/evaluate_fold_on_list.expression.yaml.expect b/pkg/front_end/testcases/expression/evaluate_fold_on_list.expression.yaml.expect
new file mode 100644
index 0000000..84d4688
--- /dev/null
+++ b/pkg/front_end/testcases/expression/evaluate_fold_on_list.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dart.core::List<dart.core::String> x, dart.core::int y) → dynamic
+  return x.{dart.core::Iterable::fold}<dart.core::int*>(0, (dart.core::int* previousValue, dart.core::String* element) → dart.core::int* => previousValue.{dart.core::num::+}(element.{dart.core::String::length}{dart.core::int*}){(dart.core::num*) →* dart.core::int*}){(dart.core::int*, (dart.core::int*, dart.core::String*) →* dart.core::int*) →* dart.core::int*};
diff --git a/pkg/front_end/testcases/expression/main.dart b/pkg/front_end/testcases/expression/main.dart
index 0c25d47..59f53f0 100644
--- a/pkg/front_end/testcases/expression/main.dart
+++ b/pkg/front_end/testcases/expression/main.dart
@@ -100,3 +100,30 @@
   T _t;
   T get t => _t;
 }
+
+void withBound<E extends String>(List<E> x) {
+  List<E> y = [];
+  List<String> z = [];
+  z.addAll(y);
+}
+
+void withBound2<E>() {
+  print(E);
+}
+
+void hasList() {
+  List<String> x = ["a", "b", "c"];
+  int xCombinedLength = x.fold<int>(
+      0, (previousValue, element) => previousValue + element.length);
+  print("xCombinedLength = $xCombinedLength");
+}
+
+void hasClosure() {
+  List<String> x() {
+    return ["hello"];
+  }
+
+  int xCombinedLength = x()
+      .fold<int>(0, (previousValue, element) => previousValue + element.length);
+  print("xCombinedLength = $xCombinedLength");
+}
diff --git a/pkg/front_end/testcases/expression/type_closure_evaluation.expression.yaml b/pkg/front_end/testcases/expression/type_closure_evaluation.expression.yaml
new file mode 100644
index 0000000..5565212
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_closure_evaluation.expression.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+# _Closure --- note that this is not what the VM sends (anymore).
+definition_types: ["dart:core", "_Closure", "1", "0"]
+type_definitions: []
+type_bounds: []
+type_defaults: []
+position: "main.dart"
+method: "hasClosure"
+expression: |
+  x().fold<int>(0, (previousValue, element) => previousValue + element.length)
diff --git a/pkg/front_end/testcases/expression/type_closure_evaluation.expression.yaml.expect b/pkg/front_end/testcases/expression/type_closure_evaluation.expression.yaml.expect
new file mode 100644
index 0000000..5865e1f
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_closure_evaluation.expression.yaml.expect
@@ -0,0 +1,9 @@
+Errors: {
+  org-dartlang-debug:synthetic_debug_expression:1:2: Error: Cannot invoke an instance of '_Closure' because it declares 'call' to be something other than a method.
+   - '_Closure' is from 'dart:core'.
+  Try changing 'call' to a method or explicitly invoke 'call'.
+  x().fold<int>(0, (previousValue, element) => previousValue + element.length)
+   ^
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dart.core::_Closure x) → dynamic
+  return invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:2: Error: Cannot invoke an instance of '_Closure' because it declares 'call' to be something other than a method.\n - '_Closure' is from 'dart:core'.\nTry changing 'call' to a method or explicitly invoke 'call'.\nx().fold<int>(0, (previousValue, element) => previousValue + element.length)\n ^"{dynamic}.fold<dart.core::int*>(0, (dynamic previousValue, dynamic element) → dynamic => previousValue{dynamic}.+(element{dynamic}.length));
diff --git a/pkg/front_end/testcases/expression/type_closure_evaluation_2.expression.yaml b/pkg/front_end/testcases/expression/type_closure_evaluation_2.expression.yaml
new file mode 100644
index 0000000..f441fdd
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_closure_evaluation_2.expression.yaml
@@ -0,0 +1,15 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+# _Closure is send as null aka dynamic.
+definition_types: ["null"]
+type_definitions: []
+type_bounds: []
+type_defaults: []
+position: "main.dart"
+method: "hasClosure"
+expression: |
+  x().fold<int>(0, (previousValue, element) => previousValue + element.length)
diff --git a/pkg/front_end/testcases/expression/type_closure_evaluation_2.expression.yaml.expect b/pkg/front_end/testcases/expression/type_closure_evaluation_2.expression.yaml.expect
new file mode 100644
index 0000000..7b31ce4
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_closure_evaluation_2.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+  return x{dynamic}.call(){dynamic}.fold<dart.core::int*>(0, (dynamic previousValue, dynamic element) → dynamic => previousValue{dynamic}.+(element{dynamic}.length));
diff --git a/pkg/front_end/testcases/expression/type_definition_bound_1.expression.yaml b/pkg/front_end/testcases/expression/type_definition_bound_1.expression.yaml
new file mode 100644
index 0000000..c8bbfc0
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_definition_bound_1.expression.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+# List<String>
+definition_types: ["dart:core", "List", "1", "1", "dart:core", "String", "1", "0"]
+type_definitions: ["E"]
+# String
+type_bounds: ["dart:core", "String", "1", "0"]
+# String
+type_defaults: ["dart:core", "String", "1", "0"]
+position: "main.dart"
+method: "withBound"
+# Can add List<E> to List<String> as E extends String.
+expression: |
+  () { List<E> y = []; x.addAll(y); }()
diff --git a/pkg/front_end/testcases/expression/type_definition_bound_1.expression.yaml.expect b/pkg/front_end/testcases/expression/type_definition_bound_1.expression.yaml.expect
new file mode 100644
index 0000000..680d8c5
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_definition_bound_1.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<E extends dart.core::String>(dart.core::List<dart.core::String> x) → dynamic
+  return (() → Null {
+    dart.core::List<#lib1::debugExpr::E*>* y = dart.core::_GrowableList::•<#lib1::debugExpr::E*>(0);
+    x.{dart.core::List::addAll}(y){(dart.core::Iterable<dart.core::String*>*) →* void};
+  })(){() →* Null};
diff --git a/pkg/front_end/testcases/expression/type_definition_bound_2.expression.yaml b/pkg/front_end/testcases/expression/type_definition_bound_2.expression.yaml
new file mode 100644
index 0000000..ca8e903
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_definition_bound_2.expression.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: ["x"]
+# List<String>
+definition_types: ["dart:core", "List", "1", "1", "dart:core", "String", "1", "0"]
+type_definitions: ["E"]
+# String
+type_bounds: ["dart:core", "String", "1", "0"]
+# String
+type_defaults: ["dart:core", "String", "1", "0"]
+position: "main.dart"
+method: "withBound"
+# Can't add List<String> to List<E> :(
+expression: |
+  () { List<E> y = []; y.addAll(x); }
diff --git a/pkg/front_end/testcases/expression/type_definition_bound_2.expression.yaml.expect b/pkg/front_end/testcases/expression/type_definition_bound_2.expression.yaml.expect
new file mode 100644
index 0000000..be07da0
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_definition_bound_2.expression.yaml.expect
@@ -0,0 +1,12 @@
+Errors: {
+  org-dartlang-debug:synthetic_debug_expression:1:31: Error: The argument type 'List<String>' can't be assigned to the parameter type 'Iterable<E>'.
+   - 'List' is from 'dart:core'.
+   - 'Iterable' is from 'dart:core'.
+  () { List<E> y = []; y.addAll(x); }
+                                ^
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<E extends dart.core::String>(dart.core::List<dart.core::String> x) → dynamic
+  return () → Null {
+    dart.core::List<#lib1::debugExpr::E*>* y = dart.core::_GrowableList::•<#lib1::debugExpr::E*>(0);
+    y.{dart.core::List::addAll}(invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:31: Error: The argument type 'List<String>' can't be assigned to the parameter type 'Iterable<E>'.\n - 'List' is from 'dart:core'.\n - 'Iterable' is from 'dart:core'.\n() { List<E> y = []; y.addAll(x); }\n                              ^" in x as{TypeError} Never){(dart.core::Iterable<#lib1::debugExpr::E*>*) →* void};
+  };
diff --git a/pkg/front_end/testcases/expression/type_definition_bound_3.expression.yaml b/pkg/front_end/testcases/expression/type_definition_bound_3.expression.yaml
new file mode 100644
index 0000000..80d4f5b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_definition_bound_3.expression.yaml
@@ -0,0 +1,16 @@
+# Copyright (c) 2022, 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.
+
+entry_point: "main.dart"
+definitions: []
+definition_types: []
+type_definitions: ["E"]
+# Object?
+type_bounds: ["dart:core", "Object", "0", "0"]
+# null (because dynamic).
+type_defaults: ["null"]
+position: "main.dart"
+method: "withBound2"
+expression: |
+  print(E)
diff --git a/pkg/front_end/testcases/expression/type_definition_bound_3.expression.yaml.expect b/pkg/front_end/testcases/expression/type_definition_bound_3.expression.yaml.expect
new file mode 100644
index 0000000..f70deb2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_definition_bound_3.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<E extends dart.core::Object? = dynamic>() → dynamic
+  return dart.core::print(#lib1::debugExpr::E*);
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.expect b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.expect
index 75defa5..1a48ce6 100644
--- a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.expect
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.expect
@@ -38,9 +38,9 @@
 // f() { m(T<R(<Z
 //       ^
 //
-// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected ';' after this.
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:14: Error: Expected ';' after this.
 // f() { m(T<R(<Z
-//               ^...
+//              ^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.modular.expect b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.modular.expect
index 75defa5..1a48ce6 100644
--- a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.modular.expect
@@ -38,9 +38,9 @@
 // f() { m(T<R(<Z
 //       ^
 //
-// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected ';' after this.
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:14: Error: Expected ';' after this.
 // f() { m(T<R(<Z
-//               ^...
+//              ^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.transformed.expect
index 75defa5..1a48ce6 100644
--- a/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart.weak.transformed.expect
@@ -38,9 +38,9 @@
 // f() { m(T<R(<Z
 //       ^
 //
-// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:15: Error: Expected ';' after this.
+// pkg/front_end/testcases/general/error_recovery/issue_38415.crash_dart:1:14: Error: Expected ';' after this.
 // f() { m(T<R(<Z
-//               ^...
+//              ^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.expect
index a49ea7c..2504ef6 100644
--- a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.expect
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.expect
@@ -22,9 +22,9 @@
 // }
 // ^
 //
-// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:4:1: Error: Expected ';' after this.
-// }
-// ^
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:9: Error: Expected ';' after this.
+//   {s A<}>
+//         ^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.modular.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.modular.expect
index a49ea7c..2504ef6 100644
--- a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.modular.expect
@@ -22,9 +22,9 @@
 // }
 // ^
 //
-// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:4:1: Error: Expected ';' after this.
-// }
-// ^
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:9: Error: Expected ';' after this.
+//   {s A<}>
+//         ^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.transformed.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.transformed.expect
index f0e2ebd..3684ba3 100644
--- a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.weak.transformed.expect
@@ -22,9 +22,9 @@
 // }
 // ^
 //
-// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:4:1: Error: Expected ';' after this.
-// }
-// ^
+// pkg/front_end/testcases/general/error_recovery/issue_39060.dart:3:9: Error: Expected ';' after this.
+//   {s A<}>
+//         ^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.expect
index 4625b85..77f4768 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.expect
@@ -6,9 +6,9 @@
 //   C c = new Object)();
 //             ^^^^^^
 //
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected ';' after this.
 //   C c = new Object)();
-//                   ^
+//             ^^^^^^
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
 //   C c = new Object)();
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.modular.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.modular.expect
index 4625b85..77f4768 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.modular.expect
@@ -6,9 +6,9 @@
 //   C c = new Object)();
 //             ^^^^^^
 //
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected ';' after this.
 //   C c = new Object)();
-//                   ^
+//             ^^^^^^
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
 //   C c = new Object)();
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.outline.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.outline.expect
index 204c7a9..ef6529e 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.outline.expect
@@ -6,9 +6,9 @@
 //   C c = new Object)();
 //             ^^^^^^
 //
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected ';' after this.
 //   C c = new Object)();
-//                   ^
+//             ^^^^^^
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
 //   C c = new Object)();
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.transformed.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.transformed.expect
index 4625b85..77f4768 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.weak.transformed.expect
@@ -6,9 +6,9 @@
 //   C c = new Object)();
 //             ^^^^^^
 //
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected ';' after this.
 //   C c = new Object)();
-//                   ^
+//             ^^^^^^
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
 //   C c = new Object)();
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index c1dac11..d59f082 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -285,7 +285,10 @@
   Future<Null> compileExpression(
       String expression,
       List<String> definitions,
+      List<String> definitionTypes,
       List<String> typeDefinitions,
+      List<String> typeBounds,
+      List<String> typeDefaults,
       String libraryUri,
       String klass,
       String method,
@@ -840,15 +843,27 @@
   Future<Null> compileExpression(
       String expression,
       List<String> definitions,
+      List<String> definitionTypes,
       List<String> typeDefinitions,
+      List<String> typeBounds,
+      List<String> typeDefaults,
       String libraryUri,
       String klass,
       String method,
       bool isStatic) async {
     final String boundaryKey = Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
-    Procedure procedure = await _generator.compileExpression(expression,
-        definitions, typeDefinitions, libraryUri, klass, method, isStatic);
+    Procedure procedure = await _generator.compileExpression(
+        expression,
+        definitions,
+        definitionTypes,
+        typeDefinitions,
+        typeBounds,
+        typeDefaults,
+        libraryUri,
+        klass,
+        method,
+        isStatic);
     if (procedure != null) {
       Component component = createExpressionEvaluationComponent(procedure);
       final IOSink sink = File(_kernelBinaryFilename).openWrite();
@@ -1127,7 +1142,10 @@
   // Note that FE will reject a compileExpression command by returning a null
   // procedure when defs or typeDefs include an illegal identifier.
   List<String> defs = <String>[];
+  List<String> defTypes = <String>[];
   List<String> typeDefs = <String>[];
+  List<String> typeBounds = <String>[];
+  List<String> typeDefaults = <String>[];
   String library;
   String klass;
   String method;
@@ -1268,7 +1286,10 @@
           compiler.compileExpression(
               compileExpressionRequest.expression,
               compileExpressionRequest.defs,
+              compileExpressionRequest.defTypes,
               compileExpressionRequest.typeDefs,
+              compileExpressionRequest.typeBounds,
+              compileExpressionRequest.typeDefaults,
               compileExpressionRequest.library,
               compileExpressionRequest.klass,
               compileExpressionRequest.method,
diff --git a/pkg/kernel/lib/library_index.dart b/pkg/kernel/lib/library_index.dart
index e2f89df..5f231b4 100644
--- a/pkg/kernel/lib/library_index.dart
+++ b/pkg/kernel/lib/library_index.dart
@@ -22,9 +22,14 @@
   final Map<String, _ClassTable> _libraries = <String, _ClassTable>{};
 
   /// Indexes the libraries with the URIs given in [libraryUris].
-  LibraryIndex(Component component, Iterable<String> libraryUris) {
+  LibraryIndex(Component component, Iterable<String> libraryUris)
+      : this.fromLibraries(component.libraries, libraryUris);
+
+  /// Indexes the libraries with the URIs given in [libraryUris].
+  LibraryIndex.fromLibraries(
+      Iterable<Library> libraries, Iterable<String> libraryUris) {
     Set<String> libraryUriSet = libraryUris.toSet();
-    for (Library library in component.libraries) {
+    for (Library library in libraries) {
       String uri = '${library.importUri}';
       if (libraryUriSet.contains(uri)) {
         _libraries[uri] = new _ClassTable(library);
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index f18f0d2..43240f8 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -500,16 +500,19 @@
   final dynamic dart_platform_kernel = request[3];
   final String expression = request[4];
   final List<String> definitions = request[5].cast<String>();
-  final List<String> typeDefinitions = request[6].cast<String>();
-  final String libraryUri = request[7];
-  final String? klass = request[8];
-  final String? method = request[9];
-  final bool isStatic = request[10];
-  final List<List<int>> dillData = request[11].cast<List<int>>();
-  final int blobLoadCount = request[12];
-  final bool enableAsserts = request[13];
+  final List<String> definitionTypes = request[6].cast<String>();
+  final List<String> typeDefinitions = request[7].cast<String>();
+  final List<String> typeBounds = request[8].cast<String>();
+  final List<String> typeDefaults = request[9].cast<String>();
+  final String libraryUri = request[10];
+  final String? klass = request[11];
+  final String? method = request[12];
+  final bool isStatic = request[13];
+  final List<List<int>> dillData = request[14].cast<List<int>>();
+  final int blobLoadCount = request[15];
+  final bool enableAsserts = request[16];
   final List<String>? experimentalFlags =
-      request[14] != null ? request[14].cast<String>() : null;
+      request[17] != null ? request[17].cast<String>() : null;
 
   IncrementalCompilerWrapper? compiler = isolateCompilers[isolateGroupId];
 
@@ -623,7 +626,10 @@
     Procedure? procedure = await compiler.generator!.compileExpression(
         expression,
         definitions,
+        definitionTypes,
         typeDefinitions,
+        typeBounds,
+        typeDefaults,
         libraryUri,
         klass,
         method,
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 08b00e7..3794fbf 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -194,23 +194,43 @@
   Future<Procedure?> compileExpression(
       String expression,
       List<String> definitions,
+      List<String> definitionTypes,
       List<String> typeDefinitions,
+      List<String> typeBounds,
+      List<String> typeDefaults,
       String libraryUri,
       String? klass,
       String? method,
       bool isStatic) {
-    Map<String, DartType> completeDefinitions = {};
-    for (int i = 0; i < definitions.length; i++) {
-      String name = definitions[i];
-      if (isLegalIdentifier(name) || (i == 0 && isExtensionThisName(name))) {
-        completeDefinitions[name] = new DynamicType();
+    ClassHierarchy? classHierarchy =
+        (_lastKnownGood ?? _combinePendingDeltas(false)).classHierarchy;
+    Map<String, DartType>? completeDefinitions = createDefinitionsWithTypes(
+        classHierarchy?.knownLibraries, definitionTypes, definitions);
+    if (completeDefinitions == null) {
+      completeDefinitions = {};
+      // No class hierarchy or wasn't provided correct types.
+      // Revert to old behaviour of setting everything to dynamic.
+      for (int i = 0; i < definitions.length; i++) {
+        String name = definitions[i];
+        if (isLegalIdentifier(name) || (i == 0 && isExtensionThisName(name))) {
+          completeDefinitions[name] = new DynamicType();
+        }
       }
     }
 
-    List<TypeParameter> typeParameters = [];
-    for (String name in typeDefinitions) {
-      if (!isLegalIdentifier(name)) continue;
-      typeParameters.add(new TypeParameter(name, new DynamicType()));
+    List<TypeParameter>? typeParameters = createTypeParametersWithBounds(
+        classHierarchy?.knownLibraries,
+        typeBounds,
+        typeDefaults,
+        typeDefinitions);
+    if (typeParameters == null) {
+      // No class hierarchy or wasn't provided correct types.
+      // Revert to old behaviour of setting everything to dynamic.
+      typeParameters = [];
+      for (String name in typeDefinitions) {
+        if (!isLegalIdentifier(name)) continue;
+        typeParameters.add(new TypeParameter(name, new DynamicType()));
+      }
     }
 
     Uri library = Uri.parse(libraryUri);
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 056d540..66cf72d 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -115,14 +115,32 @@
       await compiler.compile();
       compiler.accept();
       {
-        Procedure? procedure = await compiler.compileExpression('main',
-            <String>[], <String>[], main.uri.toString(), null, null, true);
+        Procedure? procedure = await compiler.compileExpression(
+            'main',
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            main.uri.toString(),
+            null,
+            null,
+            true);
         expect(procedure, isNotNull);
         expect(errorsReported, equals(0));
       }
       {
-        Procedure? procedure = await compiler.compileExpression('main1',
-            <String>[], <String>[], main.uri.toString(), null, null, true);
+        Procedure? procedure = await compiler.compileExpression(
+            'main1',
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            main.uri.toString(),
+            null,
+            null,
+            true);
         expect(procedure, isNotNull);
         expect(errorsReported, equals(1));
         errorsReported = 0;
@@ -1038,8 +1056,17 @@
       }
       compiler.accept();
       {
-        Procedure? procedure = await compiler.compileExpression('a', <String>[],
-            <String>[], 'package:foo/bar.dart', 'A', null, true);
+        Procedure? procedure = await compiler.compileExpression(
+            'a',
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            'package:foo/bar.dart',
+            'A',
+            null,
+            true);
         expect(procedure, isNotNull);
       }
 
@@ -1055,8 +1082,17 @@
       }
       await compiler.reject();
       {
-        Procedure? procedure = await compiler.compileExpression('a', <String>[],
-            <String>[], 'package:foo/bar.dart', 'A', null, true);
+        Procedure? procedure = await compiler.compileExpression(
+            'a',
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            'package:foo/bar.dart',
+            'A',
+            null,
+            true);
         expect(procedure, isNotNull);
       }
     });
@@ -1106,7 +1142,16 @@
       compiler.accept();
       {
         final Procedure procedure = (await compiler.compileExpression(
-            'a', <String>[], <String>[], barUri.toString(), 'A', null, true))!;
+            'a',
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            barUri.toString(),
+            'A',
+            null,
+            true))!;
         // Verify that the expression only has links to the only bar we know
         // about.
         final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
@@ -1153,7 +1198,16 @@
       }
       {
         final Procedure procedure = (await compiler.compileExpression(
-            'a', <String>[], <String>[], barUri.toString(), 'A', null, true))!;
+            'a',
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            <String>[],
+            barUri.toString(),
+            'A',
+            null,
+            true))!;
         // Verify that the expression only has links to the original bar.
         final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
         procedure.accept(lrc);
diff --git a/runtime/observatory/tests/service/evaluate_fold_on_list_test.dart b/runtime/observatory/tests/service/evaluate_fold_on_list_test.dart
new file mode 100644
index 0000000..36df1f4
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_fold_on_list_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:observatory/models.dart' show InstanceKind;
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+void testFunction() {
+  List<String> x = ["a", "b", "c"];
+  int xCombinedLength = x.fold<int>(
+      0, (previousValue, element) => previousValue + element.length);
+  debugger();
+  print("xCombinedLength = $xCombinedLength");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    Instance result = await isolate.evalFrame(0, '''x.fold<int>(
+              0, (previousValue, element) => previousValue + element.length)''')
+        as Instance;
+    expect(result.valueAsString, equals('3'));
+    expect(result.kind, equals(InstanceKind.int));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/evaluate_type_arguments_test.dart b/runtime/observatory/tests/service/evaluate_type_arguments_test.dart
new file mode 100644
index 0000000..50861ec
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_type_arguments_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:developer';
+import 'package:observatory/models.dart' show InstanceKind;
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+class A {}
+
+class B extends A {}
+
+class C extends Object with ListMixin<C> implements List<C> {
+  int length = 0;
+  C operator [](int index) => throw UnimplementedError();
+  void operator []=(int index, C value) {}
+}
+
+void testFunction4<T4 extends List<T4>>() {
+  debugger();
+  print("T4 = $T4");
+}
+
+void testFunction3<T3, S3 extends T3>() {
+  debugger();
+  print("T3 = $T3");
+  print("S3 = $S3");
+}
+
+void testFunction2<E extends String>(List<E> x) {
+  debugger();
+  print("x = $x");
+}
+
+void testFunction() {
+  testFunction2<String>(<String>["a", "b", "c"]);
+  testFunction3<A, B>();
+  testFunction4<C>();
+}
+
+void fooxx<E extends String>(List<E> y) {
+  List<E> x = new List<E>.from(["hello"]);
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    {
+      // Can add List<E extends String> to List<String> directly.
+      Instance result = await isolate.evalFrame(0, '''() {
+        List<E> y = new List<E>.from(["hello"]);
+        x.addAll(y);
+        return x.last;
+      }()''') as Instance;
+      expect(result.valueAsString, equals("hello"));
+      expect(result.kind, equals(InstanceKind.string));
+    }
+    {
+      // Can't add List<String> to List<E extends String> directly.
+      DartError result = await isolate.evalFrame(0, '''() {
+        List<E> y = [];
+        y.addAll(x);
+        return y.last;
+      }()''') as DartError;
+      expect(
+          result.message,
+          contains(
+              "The argument type '_GrowableList<String>' can't be assigned "
+              "to the parameter type 'Iterable<E>'"));
+    }
+    {
+      // Can add List<String> to List<E extends String> via cast.
+      Instance result = await isolate.evalFrame(0, '''() {
+        List<E> y = [];
+        y.addAll(x.cast());
+        return y.toString();
+      }()''') as Instance;
+      // Notice how "hello" was added a few evaluations back.
+      expect(result.valueAsString, equals("[a, b, c, hello]"));
+      expect(result.kind, equals(InstanceKind.string));
+    }
+    {
+      // Can create List<String> from List<E extends String>.
+      Instance result = await isolate.evalFrame(0, '''() {
+        List<E> y = new List<E>.from(x);
+        return y.toString();
+      }()''') as Instance;
+      // Notice how "hello" was added a few evaluations back.
+      expect(result.valueAsString, equals("[a, b, c, hello]"));
+      expect(result.kind, equals(InstanceKind.string));
+    }
+  },
+  resumeIsolate,
+  (Isolate isolate) async {
+    // This is just to make sure the VM doesn't crash.
+    Instance result =
+        await isolate.evalFrame(0, '''S3.toString()''') as Instance;
+    expect(result.valueAsString, equals("B"));
+    expect(result.kind, equals(InstanceKind.string));
+  },
+  resumeIsolate,
+  (Isolate isolate) async {
+    // This is just to make sure the VM doesn't crash.
+    Instance result =
+        await isolate.evalFrame(0, '''T4.toString()''') as Instance;
+    expect(result.valueAsString, equals("C"));
+    expect(result.kind, equals(InstanceKind.string));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/evaluate_type_with_extension_test.dart b/runtime/observatory/tests/service/evaluate_type_with_extension_test.dart
new file mode 100644
index 0000000..b998aed
--- /dev/null
+++ b/runtime/observatory/tests/service/evaluate_type_with_extension_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:observatory/models.dart' show InstanceKind;
+import 'package:observatory/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+extension on String {
+  String printAndReturnHello() {
+    String response = "Hello from String '$this'";
+    print(response);
+    return response;
+  }
+}
+
+void testFunction() {
+  String x = "hello";
+  String value = x.printAndReturnHello();
+  debugger();
+  print("value = $value");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    Instance result =
+        await isolate.evalFrame(0, 'x.printAndReturnHello()') as Instance;
+    expect(result.valueAsString, equals("Hello from String 'hello'"));
+    expect(result.kind, equals(InstanceKind.string));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index ee4f627..95723e9 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -95,6 +95,7 @@
 evaluate_activation_test: SkipByDesign
 evaluate_async_closure_test: SkipByDesign
 evaluate_class_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_fold_on_list_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_function_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_async_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_async_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
@@ -102,6 +103,8 @@
 evaluate_in_frame_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_frame_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_sync_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_type_arguments_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_type_with_extension_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_with_escaping_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
 field_script_test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/runtime/observatory_2/tests/service_2/evaluate_fold_on_list_test.dart b/runtime/observatory_2/tests/service_2/evaluate_fold_on_list_test.dart
new file mode 100644
index 0000000..87c1698
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/evaluate_fold_on_list_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:observatory_2/models.dart' show InstanceKind;
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+void testFunction() {
+  List<String> x = ["a", "b", "c"];
+  int xCombinedLength = x.fold<int>(
+      0, (previousValue, element) => previousValue + element.length);
+  debugger();
+  print("xCombinedLength = $xCombinedLength");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    Instance result = await isolate.evalFrame(0, '''x.fold<int>(
+              0, (previousValue, element) => previousValue + element.length)''')
+        as Instance;
+    expect(result.valueAsString, equals('3'));
+    expect(result.kind, equals(InstanceKind.int));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory_2/tests/service_2/evaluate_type_arguments_test.dart b/runtime/observatory_2/tests/service_2/evaluate_type_arguments_test.dart
new file mode 100644
index 0000000..694be96
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/evaluate_type_arguments_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:developer';
+import 'package:observatory_2/models.dart' show InstanceKind;
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+class A {}
+
+class B extends A {}
+
+class C extends Object with ListMixin<C> implements List<C> {
+  int length = 0;
+  C operator [](int index) => throw UnimplementedError();
+  void operator []=(int index, C value) {}
+}
+
+void testFunction4<T4 extends List<T4>>() {
+  debugger();
+  print("T4 = $T4");
+}
+
+void testFunction3<T3, S3 extends T3>() {
+  debugger();
+  print("T3 = $T3");
+  print("S3 = $S3");
+}
+
+void testFunction2<E extends String>(List<E> x) {
+  debugger();
+  print("x = $x");
+}
+
+void testFunction() {
+  testFunction2<String>(<String>["a", "b", "c"]);
+  testFunction3<A, B>();
+  testFunction4<C>();
+}
+
+void fooxx<E extends String>(List<E> y) {
+  List<E> x = new List<E>.from(["hello"]);
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    {
+      // Can add List<E extends String> to List<String> directly.
+      Instance result = await isolate.evalFrame(0, '''() {
+        List<E> y = new List<E>.from(["hello"]);
+        x.addAll(y);
+        return x.last;
+      }()''') as Instance;
+      expect(result.valueAsString, equals("hello"));
+      expect(result.kind, equals(InstanceKind.string));
+    }
+    {
+      // Can't add List<String> to List<E extends String> directly.
+      DartError result = await isolate.evalFrame(0, '''() {
+        List<E> y = [];
+        y.addAll(x);
+        return y.last;
+      }()''') as DartError;
+      expect(
+          result.message,
+          contains(
+              "The argument type '_GrowableList<String>' can't be assigned "
+              "to the parameter type 'Iterable<E>'"));
+    }
+    {
+      // Can add List<String> to List<E extends String> via cast.
+      Instance result = await isolate.evalFrame(0, '''() {
+        List<E> y = [];
+        y.addAll(x.cast());
+        return y.toString();
+      }()''') as Instance;
+      // Notice how "hello" was added a few evaluations back.
+      expect(result.valueAsString, equals("[a, b, c, hello]"));
+      expect(result.kind, equals(InstanceKind.string));
+    }
+    {
+      // Can create List<String> from List<E extends String>.
+      Instance result = await isolate.evalFrame(0, '''() {
+        List<E> y = new List<E>.from(x);
+        return y.toString();
+      }()''') as Instance;
+      // Notice how "hello" was added a few evaluations back.
+      expect(result.valueAsString, equals("[a, b, c, hello]"));
+      expect(result.kind, equals(InstanceKind.string));
+    }
+  },
+  resumeIsolate,
+  (Isolate isolate) async {
+    // This is just to make sure the VM doesn't crash.
+    Instance result =
+        await isolate.evalFrame(0, '''S3.toString()''') as Instance;
+    expect(result.valueAsString, equals("B"));
+    expect(result.kind, equals(InstanceKind.string));
+  },
+  resumeIsolate,
+  (Isolate isolate) async {
+    // This is just to make sure the VM doesn't crash.
+    Instance result =
+        await isolate.evalFrame(0, '''T4.toString()''') as Instance;
+    expect(result.valueAsString, equals("C"));
+    expect(result.kind, equals(InstanceKind.string));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory_2/tests/service_2/evaluate_type_with_extension_test.dart b/runtime/observatory_2/tests/service_2/evaluate_type_with_extension_test.dart
new file mode 100644
index 0000000..333eb89
--- /dev/null
+++ b/runtime/observatory_2/tests/service_2/evaluate_type_with_extension_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:observatory_2/models.dart' show InstanceKind;
+import 'package:observatory_2/service_io.dart';
+import 'package:test/test.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+extension on String {
+  String printAndReturnHello() {
+    String response = "Hello from String '$this'";
+    print(response);
+    return response;
+  }
+}
+
+void testFunction() {
+  String x = "hello";
+  String value = x.printAndReturnHello();
+  debugger();
+  print("value = $value");
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    Instance result =
+        await isolate.evalFrame(0, 'x.printAndReturnHello()') as Instance;
+    expect(result.valueAsString, equals("Hello from String 'hello'"));
+    expect(result.kind, equals(InstanceKind.string));
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 914b102..b27568f 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -95,6 +95,7 @@
 evaluate_activation_test: SkipByDesign
 evaluate_async_closure_test: SkipByDesign
 evaluate_class_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_fold_on_list_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_function_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_async_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_async_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
@@ -102,6 +103,8 @@
 evaluate_in_frame_rpc_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_frame_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_in_sync_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_type_arguments_test: SkipByDesign # Debugger is disabled in AOT mode.
+evaluate_type_with_extension_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_with_escaping_closure_test: SkipByDesign # Debugger is disabled in AOT mode.
 evaluate_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode.
 field_script_test: SkipByDesign # Debugger is disabled in AOT mode.
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 649bca4..d2229cd 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -208,6 +208,7 @@
         KernelIsolate::CompileExpressionToKernel(
             /*platform_kernel=*/nullptr, /*platform_kernel_size=*/0,
             expr_text.ToCString(), Array::empty_array(), Array::empty_array(),
+            Array::empty_array(), Array::empty_array(), Array::empty_array(),
             String::Handle(lib_handle.url()).ToCString(), "A",
             /* method= */ nullptr,
             /* is_static= */ false);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 7bbf92b..cb64707 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1287,7 +1287,9 @@
 TypeArgumentsPtr ActivationFrame::BuildParameters(
     const GrowableObjectArray& param_names,
     const GrowableObjectArray& param_values,
-    const GrowableObjectArray& type_params_names) {
+    const GrowableObjectArray& type_params_names,
+    const GrowableObjectArray& type_params_bounds,
+    const GrowableObjectArray& type_params_defaults) {
   GetDescIndices();
   bool type_arguments_available = false;
   String& name = String::Handle();
@@ -1329,6 +1331,12 @@
     intptr_t num_vars = function().NumTypeArguments();
     type_params_names.Grow(num_vars);
     type_params_names.SetLength(num_vars);
+    type_params_bounds.Grow(num_vars);
+    type_params_bounds.SetLength(num_vars);
+    type_params_defaults.Grow(num_vars);
+    type_params_defaults.SetLength(num_vars);
+    AbstractType& bound = AbstractType::Handle();
+    AbstractType& defaultType = AbstractType::Handle();
     TypeParameters& type_params = TypeParameters::Handle();
     Function& current = Function::Handle(function().ptr());
     intptr_t mapping_offset = num_vars;
@@ -1341,12 +1349,16 @@
       mapping_offset -= size;
       for (intptr_t j = 0; j < size; ++j) {
         name = type_params.NameAt(j);
+        bound = type_params.BoundAt(j);
+        defaultType = type_params.DefaultAt(j);
         // Write the names in backwards in terms of chain of functions.
         // But keep the order of names within the same function. so they
         // match up with the order of the types in 'type_arguments'.
         // Index:0 1 2 3 ...
         //       |Names in Grandparent| |Names in Parent| ..|Names in Child|
         type_params_names.SetAt(mapping_offset + j, name);
+        type_params_bounds.SetAt(mapping_offset + j, bound);
+        type_params_defaults.SetAt(mapping_offset + j, defaultType);
       }
     }
     if (!type_arguments.IsNull()) {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 231bc3f..0c95bd3 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -392,7 +392,9 @@
   TypeArgumentsPtr BuildParameters(
       const GrowableObjectArray& param_names,
       const GrowableObjectArray& param_values,
-      const GrowableObjectArray& type_params_names);
+      const GrowableObjectArray& type_params_names,
+      const GrowableObjectArray& type_params_bounds,
+      const GrowableObjectArray& type_params_defaults);
 
   ObjectPtr EvaluateCompiledExpression(const ExternalTypedData& kernel_data,
                                        const Array& arguments,
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index f7b5cfd..3f048319 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -181,7 +181,10 @@
             /* platform_kernel= */ nullptr, /* platform_kernel_size= */ 0,
             expr.ToCString(),
             /* definitions= */ Array::empty_array(),
+            /* definition_types= */ Array::empty_array(),
             /* type_defintions= */ Array::empty_array(),
+            /* type_bounds= */ Array::empty_array(),
+            /* type_defaults= */ Array::empty_array(),
             String::Handle(lib.url()).ToCString(),
             /* klass= */ nullptr,
             /* method= */ nullptr,
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 7e098bf..c6f3222 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -476,7 +476,10 @@
       intptr_t platform_kernel_size,
       const char* expression,
       const Array& definitions,
+      const Array& definition_types,
       const Array& type_definitions,
+      const Array& type_bounds,
+      const Array& type_defaults,
       char const* library_uri,
       char const* klass,
       char const* method,
@@ -537,6 +540,22 @@
     }
     definitions_object.value.as_array.values = definitions_array;
 
+    Dart_CObject definition_types_object;
+    intptr_t num_definition_types = definition_types.Length();
+    definition_types_object.type = Dart_CObject_kArray;
+    definition_types_object.value.as_array.length = num_definition_types;
+
+    Dart_CObject** definition_types_array =
+        new Dart_CObject*[num_definition_types];
+    for (intptr_t i = 0; i < num_definition_types; ++i) {
+      definition_types_array[i] = new Dart_CObject;
+      definition_types_array[i]->type = Dart_CObject_kString;
+      definition_types_array[i]->value.as_string = const_cast<char*>(
+          String::CheckedHandle(thread->zone(), definition_types.At(i))
+              .ToCString());
+    }
+    definition_types_object.value.as_array.values = definition_types_array;
+
     Dart_CObject type_definitions_object;
     intptr_t num_type_definitions = type_definitions.Length();
     type_definitions_object.type = Dart_CObject_kArray;
@@ -553,6 +572,35 @@
     }
     type_definitions_object.value.as_array.values = type_definitions_array;
 
+    Dart_CObject type_bounds_object;
+    intptr_t num_type_bounds = type_bounds.Length();
+    type_bounds_object.type = Dart_CObject_kArray;
+    type_bounds_object.value.as_array.length = num_type_bounds;
+
+    Dart_CObject** type_bounds_array = new Dart_CObject*[num_type_bounds];
+    for (intptr_t i = 0; i < num_type_bounds; ++i) {
+      type_bounds_array[i] = new Dart_CObject;
+      type_bounds_array[i]->type = Dart_CObject_kString;
+      type_bounds_array[i]->value.as_string = const_cast<char*>(
+          String::CheckedHandle(thread->zone(), type_bounds.At(i)).ToCString());
+    }
+    type_bounds_object.value.as_array.values = type_bounds_array;
+
+    Dart_CObject type_defaults_object;
+    intptr_t num_type_defaults = type_defaults.Length();
+    type_defaults_object.type = Dart_CObject_kArray;
+    type_defaults_object.value.as_array.length = num_type_defaults;
+
+    Dart_CObject** type_defaults_array = new Dart_CObject*[num_type_defaults];
+    for (intptr_t i = 0; i < num_type_defaults; ++i) {
+      type_defaults_array[i] = new Dart_CObject;
+      type_defaults_array[i]->type = Dart_CObject_kString;
+      type_defaults_array[i]->value.as_string = const_cast<char*>(
+          String::CheckedHandle(thread->zone(), type_defaults.At(i))
+              .ToCString());
+    }
+    type_defaults_object.value.as_array.values = type_defaults_array;
+
     Dart_CObject library_uri_object;
     library_uri_object.type = Dart_CObject_kString;
     library_uri_object.value.as_string = const_cast<char*>(library_uri);
@@ -659,7 +707,10 @@
                                    &dart_platform_kernel,
                                    &expression_object,
                                    &definitions_object,
+                                   &definition_types_object,
                                    &type_definitions_object,
+                                   &type_bounds_object,
+                                   &type_defaults_object,
                                    &library_uri_object,
                                    &class_object,
                                    &method_object,
@@ -690,11 +741,26 @@
     }
     delete[] definitions_array;
 
+    for (intptr_t i = 0; i < num_definition_types; ++i) {
+      delete definition_types_array[i];
+    }
+    delete[] definition_types_array;
+
     for (intptr_t i = 0; i < num_type_definitions; ++i) {
       delete type_definitions_array[i];
     }
     delete[] type_definitions_array;
 
+    for (intptr_t i = 0; i < num_type_bounds; ++i) {
+      delete type_bounds_array[i];
+    }
+    delete[] type_bounds_array;
+
+    for (intptr_t i = 0; i < num_type_defaults; ++i) {
+      delete type_defaults_array[i];
+    }
+    delete[] type_defaults_array;
+
     for (intptr_t i = 0; i < num_dills; ++i) {
       delete dills_array[i];
     }
@@ -1142,7 +1208,10 @@
     intptr_t platform_kernel_size,
     const char* expression,
     const Array& definitions,
+    const Array& definition_types,
     const Array& type_definitions,
+    const Array& type_bounds,
+    const Array& type_defaults,
     const char* library_url,
     const char* klass,
     const char* method,
@@ -1160,7 +1229,8 @@
   ASSERT(is_static || (klass != nullptr));
   return request.SendAndWaitForResponse(
       kernel_port, platform_kernel, platform_kernel_size, expression,
-      definitions, type_definitions, library_url, klass, method, is_static,
+      definitions, definition_types, type_definitions, type_bounds,
+      type_defaults, library_url, klass, method, is_static,
       experimental_flags_);
 }
 
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index d5d5297..08a7427 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -73,7 +73,10 @@
       intptr_t platform_kernel_size,
       const char* expression,
       const Array& definitions,
+      const Array& definition_types,
       const Array& type_definitions,
+      const Array& type_bounds,
+      const Array& type_defaults,
       const char* library_url,
       const char* klass,
       const char* method,
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 553097b..336cd88 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2857,6 +2857,51 @@
         NULL,
 };
 
+static void CollectStringifiedType(Zone* zone,
+                                   const AbstractType& type,
+                                   const GrowableObjectArray& output) {
+  Instance& instance = Instance::Handle(zone);
+  if (type.IsFunctionType()) {
+    // The closure class
+    // (IsolateGroup::Current()->object_store()->closure_class())
+    // is statically typed weird (the call method redirects to itself)
+    // and the type is therefore not useful for the CFE. We use null instead.
+    output.Add(instance);
+    return;
+  }
+  if (type.IsDynamicType()) {
+    // Dynamic is weird in that it seems to have a class with no name and a
+    // library called something like '7189777121420'. We use null instead.
+    output.Add(instance);
+    return;
+  }
+  if (type.IsTypeParameter() && type.IsAbstractType()) {
+    // Calling type_class on an abstract type parameter will crash the VM.
+    // We use null instead.
+    output.Add(instance);
+    return;
+  }
+  const Class& cls = Class::Handle(type.type_class());
+  const Library& lib = Library::Handle(zone, cls.library());
+
+  instance ^= lib.url();
+  output.Add(instance);
+
+  instance ^= cls.ScrubbedName();
+  output.Add(instance);
+
+  instance ^= Smi::New((intptr_t)type.nullability());
+  output.Add(instance);
+
+  const TypeArguments& srcArguments = TypeArguments::Handle(type.arguments());
+  instance ^= Smi::New(srcArguments.Length());
+  output.Add(instance);
+  for (int i = 0; i < srcArguments.Length(); i++) {
+    const AbstractType& src_type = AbstractType::Handle(srcArguments.TypeAt(i));
+    CollectStringifiedType(zone, src_type, output);
+  }
+}
+
 static void BuildExpressionEvaluationScope(Thread* thread, JSONStream* js) {
   if (CheckDebuggerDisabled(thread, js)) {
     return;
@@ -2877,6 +2922,10 @@
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
   const GrowableObjectArray& type_params_names =
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+  const GrowableObjectArray& type_params_bounds =
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+  const GrowableObjectArray& type_params_defaults =
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
   String& klass_name = String::Handle(zone);
   String& method_name = String::Handle(zone);
   String& library_uri = String::Handle(zone);
@@ -2896,7 +2945,8 @@
     }
 
     ActivationFrame* frame = stack->FrameAt(framePos);
-    frame->BuildParameters(param_names, param_values, type_params_names);
+    frame->BuildParameters(param_names, param_values, type_params_names,
+                           type_params_bounds, type_params_defaults);
 
     if (frame->function().is_static()) {
       const Class& cls = Class::Handle(zone, frame->function().Owner());
@@ -2976,6 +3026,28 @@
       jsonParamNames.AddValue(param_name.ToCString());
     }
   }
+  {
+    const JSONArray jsonParamTypes(&report, "param_types");
+    Object& obj = Object::Handle();
+    Instance& instance = Instance::Handle();
+    const GrowableObjectArray& param_types =
+        GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+    AbstractType& type = AbstractType::Handle();
+    for (intptr_t i = 0; i < param_names.Length(); i++) {
+      obj = param_values.At(i);
+      if (obj.IsNull()) {
+        param_types.Add(obj);
+      } else if (obj.IsInstance()) {
+        instance ^= param_values.At(i);
+        type = instance.GetType(Heap::kNew);
+        CollectStringifiedType(zone, type, param_types);
+      }
+    }
+    for (intptr_t i = 0; i < param_types.Length(); i++) {
+      instance ^= param_types.At(i);
+      jsonParamTypes.AddValue(instance.ToCString());
+    }
+  }
 
   {
     JSONArray jsonTypeParamsNames(&report, "type_params_names");
@@ -2985,6 +3057,36 @@
       jsonTypeParamsNames.AddValue(type_param_name.ToCString());
     }
   }
+  {
+    const JSONArray jsonParamTypes(&report, "type_params_bounds");
+    const GrowableObjectArray& type_params_bounds_strings =
+        GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+    AbstractType& type = AbstractType::Handle();
+    for (intptr_t i = 0; i < type_params_bounds.Length(); i++) {
+      type ^= type_params_bounds.At(i);
+      CollectStringifiedType(zone, type, type_params_bounds_strings);
+    }
+    Instance& instance = Instance::Handle();
+    for (intptr_t i = 0; i < type_params_bounds_strings.Length(); i++) {
+      instance ^= type_params_bounds_strings.At(i);
+      jsonParamTypes.AddValue(instance.ToCString());
+    }
+  }
+  {
+    const JSONArray jsonParamTypes(&report, "type_params_defaults");
+    const GrowableObjectArray& type_params_defaults_strings =
+        GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+    AbstractType& type = AbstractType::Handle();
+    for (intptr_t i = 0; i < type_params_defaults.Length(); i++) {
+      type ^= type_params_defaults.At(i);
+      CollectStringifiedType(zone, type, type_params_defaults_strings);
+    }
+    Instance& instance = Instance::Handle();
+    for (intptr_t i = 0; i < type_params_defaults_strings.Length(); i++) {
+      instance ^= type_params_defaults_strings.At(i);
+      jsonParamTypes.AddValue(instance.ToCString());
+    }
+  }
   report.AddProperty("libraryUri", library_uri.ToCString());
   if (!klass_name.IsNull()) {
     report.AddProperty("klass", klass_name.ToCString());
@@ -3036,7 +3138,10 @@
     RUNNABLE_ISOLATE_PARAMETER,
     new StringParameter("expression", true),
     new StringParameter("definitions", false),
+    new StringParameter("definitionTypes", false),
     new StringParameter("typeDefinitions", false),
+    new StringParameter("typeBounds", false),
+    new StringParameter("typeDefaults", false),
     new StringParameter("libraryUri", true),
     new StringParameter("klass", false),
     new BoolParameter("isStatic", false),
@@ -3070,6 +3175,12 @@
     PrintInvalidParamError(js, "definitions");
     return;
   }
+  const GrowableObjectArray& param_types =
+      GrowableObjectArray::Handle(thread->zone(), GrowableObjectArray::New());
+  if (!ParseCSVList(js->LookupParam("definitionTypes"), param_types)) {
+    PrintInvalidParamError(js, "definitionTypes");
+    return;
+  }
 
   const GrowableObjectArray& type_params =
       GrowableObjectArray::Handle(thread->zone(), GrowableObjectArray::New());
@@ -3077,6 +3188,18 @@
     PrintInvalidParamError(js, "typedDefinitions");
     return;
   }
+  const GrowableObjectArray& type_bounds =
+      GrowableObjectArray::Handle(thread->zone(), GrowableObjectArray::New());
+  if (!ParseCSVList(js->LookupParam("typeBounds"), type_bounds)) {
+    PrintInvalidParamError(js, "typeBounds");
+    return;
+  }
+  const GrowableObjectArray& type_defaults =
+      GrowableObjectArray::Handle(thread->zone(), GrowableObjectArray::New());
+  if (!ParseCSVList(js->LookupParam("typeDefaults"), type_defaults)) {
+    PrintInvalidParamError(js, "typeDefaults");
+    return;
+  }
 
   const uint8_t* kernel_buffer = Service::dart_library_kernel();
   const intptr_t kernel_buffer_len = Service::dart_library_kernel_length();
@@ -3085,7 +3208,10 @@
       KernelIsolate::CompileExpressionToKernel(
           kernel_buffer, kernel_buffer_len, js->LookupParam("expression"),
           Array::Handle(Array::MakeFixedLength(params)),
+          Array::Handle(Array::MakeFixedLength(param_types)),
           Array::Handle(Array::MakeFixedLength(type_params)),
+          Array::Handle(Array::MakeFixedLength(type_bounds)),
+          Array::Handle(Array::MakeFixedLength(type_defaults)),
           js->LookupParam("libraryUri"), js->LookupParam("klass"),
           js->LookupParam("method"), is_static);
 
@@ -3145,6 +3271,10 @@
   }
   const GrowableObjectArray& type_params_names =
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+  const GrowableObjectArray& type_params_bounds =
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+  const GrowableObjectArray& type_params_defaults =
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
 
   const ExternalTypedData& kernel_data = ExternalTypedData::Handle(
       zone, DecodeKernelBuffer(js->LookupParam("kernelBytes")));
@@ -3160,7 +3290,8 @@
     ActivationFrame* frame = stack->FrameAt(frame_pos);
     TypeArguments& type_arguments = TypeArguments::Handle(
         zone,
-        frame->BuildParameters(param_names, param_values, type_params_names));
+        frame->BuildParameters(param_names, param_values, type_params_names,
+                               type_params_bounds, type_params_defaults));
 
     const Object& result = Object::Handle(
         zone,
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 5242592..31187eb 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -648,7 +648,9 @@
         KernelIsolate::CompileExpressionToKernel(
             /* platform_kernel= */ nullptr, /* platform_kernel_size= */ 0,
             expr.ToCString(), param_names, Array::empty_array(),
-            String::Handle(lib.url()).ToCString(), /* klass= */ nullptr,
+            Array::empty_array(), Array::empty_array(), Array::empty_array(),
+            String::Handle(lib.url()).ToCString(),
+            /* klass= */ nullptr,
             /* method= */ nullptr,
             /* is_static= */ true);
     if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 867dd32..8e6a103 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -39,7 +39,6 @@
 # ......dartanalyzer
 # ......dartdevc
 # ......utils/gen_snapshot or utils/gen_snapshot.exe (if not on ia32)
-# ......pub
 # ......snapshots/
 # ........analysis_server.dart.snapshot
 # ........dart2js.dart.snapshot
@@ -88,16 +87,12 @@
 # ......api_readme.md
 
 # Scripts that go under bin/
-_platform_sdk_scripts = [
-  "dartanalyzer",
-  "pub",
-]
+_platform_sdk_scripts = [ "dartanalyzer" ]
 
 _full_sdk_scripts = [
   "dart2js",
   "dartanalyzer",
   "dartdevc",
-  "pub",
 ]
 
 # Snapshots that go under bin/snapshots
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
deleted file mode 100644
index 7eb8b0d..0000000
--- a/sdk/bin/pub.bat
+++ /dev/null
@@ -1,56 +0,0 @@
-@echo off
-REM Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-REM for details. All rights reserved. Use of this source code is governed by a
-REM BSD-style license that can be found in the LICENSE file.
-
-rem Run pub.dart on the Dart VM. This script is only used when running pub from
-rem within the Dart source repo. The shipped SDK instead uses "pub_sdk.bat",
-rem which is renamed to "pub.bat" when the SDK is built.
-
-setlocal
-rem Handle the case where dart-sdk/bin has been symlinked to.
-set DIR_NAME_WITH_SLASH=%~dp0
-set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
-call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
-rem Get rid of surrounding quotes.
-for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
-
-rem Get absolute full name for SDK_DIR.
-for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi
-
-rem Remove trailing backslash if there is one
-IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
-
-set VM_OPTIONS=
-
-rem We allow extra vm options to be passed in through an environment variable.
-if not "_%DART_VM_OPTIONS%_" == "__" (
-  set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS%
-)
-
-rem Use the Dart binary in the built SDK so pub can find the version file next
-rem to it.
-set BUILD_DIR=%SDK_DIR%\..\out\ReleaseX64
-set DART=%BUILD_DIR%\dart-sdk\bin\dart
-
-rem Run pub.
-set PUB="%SDK_DIR%\..\third_party\pkg\pub\bin\pub.dart"
-"%DART%" "--packages=%SDK_DIR%\..\.packages" %VM_OPTIONS% "%PUB%" %*
-
-endlocal
-
-exit /b %errorlevel%
-
-:follow_links
-setlocal
-for %%i in (%1) do set result=%%~fi
-set current=
-for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
-                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
-  set current=%%i
-)
-if not "%current%"=="" call :follow_links "%current%", result
-endlocal & set %~2=%result%
-goto :eof
-
-:end
diff --git a/sdk/bin/pub_sdk b/sdk/bin/pub_sdk
deleted file mode 100755
index 17ce14c..0000000
--- a/sdk/bin/pub_sdk
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2014, 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.
-
-# Run pub.dart on the Dart VM. This script assumes the Dart SDK's directory
-# structure.
-
-function follow_links() {
-  file="$1"
-  while [ -h "$file" ]; do
-    # On Mac OS, readlink -f doesn't work.
-    file="$(readlink "$file")"
-  done
-  echo "$file"
-}
-
-function array_contains() {
-  local needle="$1"
-  local element
-  shift
-  for element; do [ "$element" = "$needle" ] && return 0; done
-  return 1
-}
-
-# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
-PROG_NAME="$(follow_links "$BASH_SOURCE")"
-
-# Handle the case where dart-sdk/bin has been symlinked to.
-BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-DART="$BIN_DIR/dart"
-
-unset VM_OPTIONS
-declare -a VM_OPTIONS
-
-# Allow extra VM options to be passed in through an environment variable.
-if [[ $DART_VM_OPTIONS ]]; then
-  read -a OPTIONS <<< "$DART_VM_OPTIONS"
-  VM_OPTIONS+=("${OPTIONS[@]}")
-fi
-
-if [ -t 2 ]; then # Only print warning when run in terminal.
-  >&2 echo 'The top level `pub` command is deprecated. Use `dart pub` instead.'
-fi
-
-# Forward to the `dart __deprecatedpub` command.
-exec "$DART" "${VM_OPTIONS[@]}" __deprecated_pub "$@"
diff --git a/sdk/bin/pub_sdk.bat b/sdk/bin/pub_sdk.bat
deleted file mode 100644
index e882aac..0000000
--- a/sdk/bin/pub_sdk.bat
+++ /dev/null
@@ -1,50 +0,0 @@
-@echo off
-REM Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-REM for details. All rights reserved. Use of this source code is governed by a
-REM BSD-style license that can be found in the LICENSE file.
-
-setlocal
-rem Handle the case where dart-sdk/bin has been symlinked to.
-set DIR_NAME_WITH_SLASH=%~dp0
-set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
-call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
-rem Get rid of surrounding quotes.
-for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
-
-rem Get absolute full name for SDK_DIR.
-for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi
-
-rem Remove trailing backslash if there is one
-IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
-
-set VM_OPTIONS=
-set USING_DART_1=
-
-rem We allow extra vm options to be passed in through an environment variable.
-if not "_%DART_VM_OPTIONS%_" == "__" (
-  set VM_OPTIONS=%VM_OPTIONS% %DART_VM_OPTIONS%
-  for %%o in (%DART_VM_OPTIONS%) do (
-    if "%%o" equ "--no-preview-dart-2" set USING_DART_1=y
-  )
-)
-
-echo "The top level `pub.bat` command is deprecated. Use `dart pub` instead." 1>&2
-"%BIN_DIR%\dart" %VM_OPTIONS% __deprecated_pub %*
-
-endlocal
-
-exit /b %errorlevel%
-
-:follow_links
-setlocal
-for %%i in (%1) do set result=%%~fi
-set current=
-for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
-                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
-  set current=%%i
-)
-if not "%current%"=="" call :follow_links "%current%", result
-endlocal & set %~2=%result%
-goto :eof
-
-:end
diff --git a/sdk/lib/vmservice/running_isolates.dart b/sdk/lib/vmservice/running_isolates.dart
index 17ba448..e699cb3 100644
--- a/sdk/lib/vmservice/running_isolates.dart
+++ b/sdk/lib/vmservice/running_isolates.dart
@@ -124,7 +124,10 @@
       'isolateId': _message.params['isolateId']!,
       'expression': _message.params['expression']!,
       'definitions': buildScopeResponseResult['param_names']!,
+      'definitionTypes': buildScopeResponseResult['param_types']!,
       'typeDefinitions': buildScopeResponseResult['type_params_names']!,
+      'typeBounds': buildScopeResponseResult['type_params_bounds']!,
+      'typeDefaults': buildScopeResponseResult['type_params_defaults']!,
       'libraryUri': buildScopeResponseResult['libraryUri']!,
       'isStatic': buildScopeResponseResult['isStatic']!,
     };
diff --git a/tools/VERSION b/tools/VERSION
index 7b31a36..6acbdae75 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 69
+PRERELEASE 70
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/pub_integration_test.py b/tools/bots/pub_integration_test.py
index f80c554..4f35ae6 100755
--- a/tools/bots/pub_integration_test.py
+++ b/tools/bots/pub_integration_test.py
@@ -35,10 +35,10 @@
     mode = ('Debug' if options.mode == 'debug' else 'Release')
 
     out_dir = 'xcodebuild' if sys.platform == 'darwin' else 'out'
-    extension = '' if not sys.platform == 'win32' else '.bat'
-    pub = os.path.abspath('%s/%s%s/dart-sdk/bin/pub%s' %
-                          (out_dir, mode, arch, extension))
-    print(pub)
+    extension = '' if not sys.platform == 'win32' else '.exe'
+    dart = os.path.abspath('%s/%s%s/dart-sdk/bin/dart%s' %
+                           (out_dir, mode, arch, extension))
+    print(dart)
 
     working_dir = tempfile.mkdtemp()
     try:
@@ -49,11 +49,15 @@
         with open(working_dir + '/pubspec.yaml', 'w') as pubspec_yaml:
             pubspec_yaml.write(PUBSPEC)
 
-        exit_code = subprocess.call([pub, 'get'], cwd=working_dir, env=env)
+        exit_code = subprocess.call([dart, 'pub', 'get'],
+                                    cwd=working_dir,
+                                    env=env)
         if exit_code != 0:
             return exit_code
 
-        exit_code = subprocess.call([pub, 'upgrade'], cwd=working_dir, env=env)
+        exit_code = subprocess.call([dart, 'pub', 'upgrade'],
+                                    cwd=working_dir,
+                                    env=env)
         if exit_code != 0:
             return exit_code
     finally:
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 1d376fe..a73165a 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1543,6 +1543,7 @@
       "builders": [
         "vm-kernel-precomp-linux-debug-x64",
         "vm-kernel-precomp-linux-debug-x64c",
+        "vm-kernel-precomp-linux-debug-simarm",
         "vm-kernel-precomp-linux-debug-simarm64",
         "vm-kernel-precomp-linux-debug-simarm64c",
         "vm-kernel-precomp-linux-debug-simriscv32",
@@ -1805,8 +1806,11 @@
     },
     {
       "builders": [
+        "vm-kernel-linux-debug-simarm",
         "vm-kernel-linux-debug-simarm64",
         "vm-kernel-linux-debug-simarm64c",
+        "vm-kernel-linux-debug-simriscv32",
+        "vm-kernel-linux-debug-simriscv64",
         "vm-kernel-linux-release-simarm",
         "vm-kernel-linux-release-simarm64",
         "vm-kernel-linux-release-simarm64c",
diff --git a/tools/linux_dist_support/linux_distribution_support.py b/tools/linux_dist_support/linux_distribution_support.py
index 44c7477..b7c5529 100644
--- a/tools/linux_dist_support/linux_distribution_support.py
+++ b/tools/linux_dist_support/linux_distribution_support.py
@@ -125,9 +125,6 @@
         Run(['/usr/lib/dart/bin/dartanalyzer', test_file])
         Run(['/usr/lib/dart/bin/dart', test_file])
 
-    # Sanity check that pub can start up and print the version
-    Run(['/usr/lib/dart/bin/pub', '--version'])
-
     UninstallDart()
     TestInstallation(assume_installed=False)