Version 2.13.0-159.0.dev

Merge commit 'd82ecdfe01e1fd4cd8484ac920a1dea5761dc273' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c23620..871a73d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@
 
 ### Core libraries
 
+#### `dart:collection`
+
+- The `SplayTreeMap` was changed to allow `null` as key if the `compare`
+  function allows it. It now checks that a new key can be used as an
+  argument to the `compare` function when the member is added,
+  *even if the map is empty* (in which case it just compares the key
+  to itself).
+- The `SplayTreeSet` was changed to checks that a new element can be used as an
+  argument to the `compare` function when the member is added,
+  *even if the set is empty* (in which case it just compares the element
+  to itself).
+
 ### Dart VM
 
 ### Tools
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
index c56e6e9..beaf3f5 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -8,7 +8,6 @@
 
 // ignore_for_file: annotate_overrides
 // ignore_for_file: unnecessary_parenthesis
-// ignore_for_file: unused_shown_name
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -16,8 +15,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/json_parsing.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart'
-    show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:meta/meta.dart';
 
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 6559e10..03bb36c 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -8,7 +8,6 @@
 
 // ignore_for_file: annotate_overrides
 // ignore_for_file: unnecessary_parenthesis
-// ignore_for_file: unused_shown_name
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -16,8 +15,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/json_parsing.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart'
-    show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:meta/meta.dart';
 
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 0836959..d697810 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -385,7 +385,7 @@
     ..outdent()
     ..writeIndentedln('}');
   namespace.members.whereType<Const>().forEach((cons) {
-    // We don't use any deprecated enum values, so ommit them entirely.
+    // We don't use any deprecated enum values, so omit them entirely.
     if (cons.isDeprecated) {
       return;
     }
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 3475f3a..a45cba0 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -161,7 +161,6 @@
 
 // ignore_for_file: annotate_overrides
 // ignore_for_file: unnecessary_parenthesis
-// ignore_for_file: unused_shown_name
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -169,8 +168,7 @@
 import 'package:analysis_server/lsp_protocol/protocol${importCustom ? '_custom' : ''}_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/json_parsing.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart'
-    show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:meta/meta.dart';
 
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 7ab99dd..05a61d7 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -3263,9 +3263,10 @@
    */
   static const CompileTimeErrorCode EXTENDS_DEFERRED_CLASS =
       CompileTimeErrorCode(
-          'EXTENDS_DEFERRED_CLASS', "Classes can't extend deferred classes.",
+          'SUBTYPE_OF_DEFERRED_CLASS', "Classes can't extend deferred classes.",
           correction: "Try specifying a different superclass, or "
-              "removing the extends clause.");
+              "removing the extends clause.",
+          uniqueName: 'EXTENDS_DEFERRED_CLASS');
 
   /**
    * Parameters:
@@ -4772,11 +4773,12 @@
    * See [EXTENDS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode IMPLEMENTS_DEFERRED_CLASS =
-      CompileTimeErrorCode('IMPLEMENTS_DEFERRED_CLASS',
+      CompileTimeErrorCode('SUBTYPE_OF_DEFERRED_CLASS',
           "Classes and mixins can't implement deferred classes.",
           correction: "Try specifying a different interface, "
               "removing the class from the list, or "
-              "changing the import to not be deferred.");
+              "changing the import to not be deferred.",
+          uniqueName: 'IMPLEMENTS_DEFERRED_CLASS');
 
   /**
    * Parameters:
@@ -7199,8 +7201,9 @@
    * See [EXTENDS_DEFERRED_CLASS], and [IMPLEMENTS_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode MIXIN_DEFERRED_CLASS = CompileTimeErrorCode(
-      'MIXIN_DEFERRED_CLASS', "Classes can't mixin deferred classes.",
-      correction: "Try changing the import to not be deferred.");
+      'SUBTYPE_OF_DEFERRED_CLASS', "Classes can't mixin deferred classes.",
+      correction: "Try changing the import to not be deferred.",
+      uniqueName: 'MIXIN_DEFERRED_CLASS');
 
   static const CompileTimeErrorCode
       MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES = CompileTimeErrorCode(
@@ -8171,11 +8174,11 @@
    */
   static const CompileTimeErrorCode
       NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY = CompileTimeErrorCode(
-          'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
               "a 'const' list.",
-          correction:
-              "Try removing the keyword 'const' from the list literal.");
+          correction: "Try removing the keyword 'const' from the list literal.",
+          uniqueName: 'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY');
 
   /**
    * No parameters.
@@ -8275,10 +8278,11 @@
    */
   static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
-          'NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as keys in a "
               "const map literal.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.",
+          uniqueName: 'NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY');
 
   /**
    * No parameters.
@@ -8328,10 +8332,11 @@
    */
   static const CompileTimeErrorCode
       NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY = CompileTimeErrorCode(
-          'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
               "a const map literal.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.",
+          uniqueName: 'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY');
 
   /**
    * No parameters.
@@ -10412,10 +10417,11 @@
 
   static const CompileTimeErrorCode SET_ELEMENT_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
-          'SET_ELEMENT_FROM_DEFERRED_LIBRARY',
+          'COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
               "a const set.",
-          correction: "Try making the deferred import non-deferred.");
+          correction: "Try making the deferred import non-deferred.",
+          uniqueName: 'SET_ELEMENT_FROM_DEFERRED_LIBRARY');
 
   /**
    * Parameters:
diff --git a/runtime/vm/compiler/backend/flow_graph_test.cc b/runtime/vm/compiler/backend/flow_graph_test.cc
index 55323bb..00baa85 100644
--- a/runtime/vm/compiler/backend/flow_graph_test.cc
+++ b/runtime/vm/compiler/backend/flow_graph_test.cc
@@ -41,7 +41,6 @@
   Definition* v0;
   PhiInstr* loop_var;
   Definition* add1;
-  ReturnInstr* ret;
 
   {
     BlockBuilder builder(H.flow_graph(), normal_entry);
@@ -70,7 +69,7 @@
 
   {
     BlockBuilder builder(H.flow_graph(), loop_exit);
-    ret = builder.AddReturn(new Value(loop_var));
+    builder.AddReturn(new Value(loop_var));
   }
 
   H.FinishGraph();
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 6ecbbf7..04ad892 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -1348,6 +1348,7 @@
   } else if (auto check = current->AsGenericCheckBound()) {
     ASSERT(CompilerState::Current().is_aot());  // non-speculative in AOT only
     // Does not deopt, so no need for licm_hoisted flag.
+    USE(check);
   } else if (auto check = current->AsTestCids()) {
     check->set_licm_hoisted(true);
   } else if (auto check = current->AsAssertAssignable()) {
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index d065d8f..06fbd70 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -14,7 +14,7 @@
 // Default ArrayStorageTraits use an Array to store HashTable contents.
 struct ArrayStorageTraits {
   using ArrayHandle = Array;
-  using ArrayPtr = ArrayPtr;
+  using ArrayPtr = dart::ArrayPtr;
 
   static ArrayHandle& PtrToHandle(ArrayPtr ptr) { return Array::Handle(ptr); }
 
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 2ad35f6..5770c5b 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -11,8 +11,8 @@
 class _SplayTreeNode<K, Node extends _SplayTreeNode<K, Node>> {
   final K key;
 
-  Node? left;
-  Node? right;
+  Node? _left;
+  Node? _right;
 
   _SplayTreeNode(this.key);
 }
@@ -24,11 +24,19 @@
 
 /// A node in a splay tree based map.
 ///
-/// A [_SplayTreeNode] that also contains a value
-class _SplayTreeMapNode<K, V>
-    extends _SplayTreeNode<K, _SplayTreeMapNode<K, V>> {
-  V value;
+/// A [_SplayTreeNode] that also contains a value,
+/// and which implements [MapEntry].
+class _SplayTreeMapNode<K, V> extends _SplayTreeNode<K, _SplayTreeMapNode<K, V>>
+    implements MapEntry<K, V> {
+  final V value;
   _SplayTreeMapNode(K key, this.value) : super(key);
+
+  _SplayTreeMapNode<K, V> _replaceValue(V value) =>
+      _SplayTreeMapNode<K, V>(key, value)
+        .._left = _left
+        .._right = _right;
+
+  String toString() => "MapEntry($key: $value)";
 }
 
 /// A splay tree is a self-balancing binary search tree.
@@ -72,7 +80,12 @@
   /// Returns the result of comparing the new root of the tree to [key].
   /// Returns -1 if the table is empty.
   int _splay(K key) {
-    if (_root == null) return -1;
+    var root = _root;
+    if (root == null) {
+      // Ensure key is compatible with `_compare`.
+      _compare(key, key);
+      return -1;
+    }
 
     // The right and newTreeRight variables start out null, and are set
     // after the first move left.  The right node is the destination
@@ -85,22 +98,22 @@
     Node? newTreeRight;
     Node? left;
     Node? newTreeLeft;
-    var current = _root!;
+    var current = root;
     // Hoist the field read out of the loop.
     var compare = _compare;
     int comp;
     while (true) {
       comp = compare(current.key, key);
       if (comp > 0) {
-        var currentLeft = current.left;
+        var currentLeft = current._left;
         if (currentLeft == null) break;
         comp = compare(currentLeft.key, key);
         if (comp > 0) {
           // Rotate right.
-          current.left = currentLeft.right;
-          currentLeft.right = current;
+          current._left = currentLeft._right;
+          currentLeft._right = current;
           current = currentLeft;
-          currentLeft = current.left;
+          currentLeft = current._left;
           if (currentLeft == null) break;
         }
         // Link right.
@@ -108,20 +121,20 @@
           // First left rebalance, store the eventual right child
           newTreeRight = current;
         } else {
-          right.left = current;
+          right._left = current;
         }
         right = current;
         current = currentLeft;
       } else if (comp < 0) {
-        var currentRight = current.right;
+        var currentRight = current._right;
         if (currentRight == null) break;
         comp = compare(currentRight.key, key);
         if (comp < 0) {
           // Rotate left.
-          current.right = currentRight.left;
-          currentRight.left = current;
+          current._right = currentRight._left;
+          currentRight._left = current;
           current = currentRight;
-          currentRight = current.right;
+          currentRight = current._right;
           if (currentRight == null) break;
         }
         // Link left.
@@ -129,7 +142,7 @@
           // First right rebalance, store the eventual left child
           newTreeLeft = current;
         } else {
-          left.right = current;
+          left._right = current;
         }
         left = current;
         current = currentRight;
@@ -139,16 +152,17 @@
     }
     // Assemble.
     if (left != null) {
-      left.right = current.left;
-      current.left = newTreeLeft;
+      left._right = current._left;
+      current._left = newTreeLeft;
     }
     if (right != null) {
-      right.left = current.right;
-      current.right = newTreeRight;
+      right._left = current._right;
+      current._right = newTreeRight;
     }
-    _root = current;
-
-    _splayCount++;
+    if (!identical(_root, current)) {
+      _root = current;
+      _splayCount++;
+    }
     return comp;
   }
 
@@ -158,13 +172,13 @@
   // in any parent tree or root pointer.
   Node _splayMin(Node node) {
     var current = node;
-    var nextLeft = current.left;
+    var nextLeft = current._left;
     while (nextLeft != null) {
       var left = nextLeft;
-      current.left = left.right;
-      left.right = current;
+      current._left = left._right;
+      left._right = current;
       current = left;
-      nextLeft = current.left;
+      nextLeft = current._left;
     }
     return current;
   }
@@ -176,13 +190,13 @@
   // in any parent tree or root pointer.
   Node _splayMax(Node node) {
     var current = node;
-    var nextRight = current.right;
+    var nextRight = current._right;
     while (nextRight != null) {
       var right = nextRight;
-      current.right = right.left;
-      right.left = current;
+      current._right = right._left;
+      right._left = current;
       current = right;
-      nextRight = current.right;
+      nextRight = current._right;
     }
     return current;
   }
@@ -193,19 +207,19 @@
     if (comp != 0) return null;
     var root = _root!;
     var result = root;
-    var left = root.left;
+    var left = root._left;
     _count--;
     // assert(_count >= 0);
     if (left == null) {
-      _root = root.right;
+      _root = root._right;
     } else {
-      var right = root.right;
+      var right = root._right;
       // Splay to make sure that the new root has an empty right child.
       root = _splayMax(left);
 
       // Insert the original right child as the right child of the new
       // root.
-      root.right = right;
+      root._right = right;
       _root = root;
     }
     _modificationCount++;
@@ -226,13 +240,13 @@
     }
     // assert(_count >= 0);
     if (comp < 0) {
-      node.left = root;
-      node.right = root.right;
-      root.right = null;
+      node._left = root;
+      node._right = root._right;
+      root._right = null;
     } else {
-      node.right = root;
-      node.left = root.left;
-      root.left = null;
+      node._right = root;
+      node._left = root._left;
+      root._left = null;
     }
     _root = node;
   }
@@ -256,6 +270,10 @@
     _count = 0;
     _modificationCount++;
   }
+
+  bool _containsKey(Object? key) {
+    return _validKey(key) && _splay(key as dynamic) == 0;
+  }
 }
 
 int _dynamicCompare(dynamic a, dynamic b) => Comparable.compare(a, b);
@@ -273,8 +291,8 @@
 
 /// A [Map] of objects that can be ordered relative to each other.
 ///
-/// The map is based on a self-balancing binary tree. It allows most operations
-/// in amortized logarithmic time.
+/// The map is based on a self-balancing binary tree.
+/// It allows most single-entry operations in amortized logarithmic time.
 ///
 /// Keys of the map are compared using the `compare` function passed in
 /// the constructor, both for ordering and for equality.
@@ -303,7 +321,7 @@
       [int Function(K key1, K key2)? compare,
       bool Function(dynamic potentialKey)? isValidKey])
       : _compare = compare ?? _defaultCompare<K>(),
-        _validKey = isValidKey ?? ((dynamic v) => v is K);
+        _validKey = isValidKey ?? ((dynamic a) => a is K);
 
   /// Creates a [SplayTreeMap] that contains all key/value pairs of [other].
   ///
@@ -385,19 +403,19 @@
   }
 
   void operator []=(K key, V value) {
-    if (key == null) throw ArgumentError(key);
     // Splay on the key to move the last node on the search path for
     // the key to the root of the tree.
     int comp = _splay(key);
     if (comp == 0) {
-      _root!.value = value;
+      _root = _root!._replaceValue(value);
+      // To represent structure change, in case someone caches the old node.
+      _splayCount += 1;
       return;
     }
     _addNewRoot(_SplayTreeMapNode(key, value), comp);
   }
 
   V putIfAbsent(K key, V ifAbsent()) {
-    if (key == null) throw ArgumentError(key);
     int comp = _splay(key);
     if (comp == 0) {
       return _root!.value;
@@ -417,6 +435,49 @@
     return value;
   }
 
+  V update(K key, V update(V value), {V Function()? ifAbsent}) {
+    var comp = _splay(key);
+    if (comp == 0) {
+      var modificationCount = _modificationCount;
+      var splayCount = _splayCount;
+      var newValue = update(_root!.value);
+      if (modificationCount != _modificationCount) {
+        throw ConcurrentModificationError(this);
+      }
+      if (splayCount != _splayCount) {
+        _splay(key);
+      }
+      _root = _root!._replaceValue(newValue);
+      _splayCount += 1;
+      return newValue;
+    }
+    if (ifAbsent != null) {
+      var modificationCount = _modificationCount;
+      var splayCount = _splayCount;
+      var newValue = ifAbsent();
+      if (modificationCount != _modificationCount) {
+        throw ConcurrentModificationError(this);
+      }
+      if (splayCount != _splayCount) {
+        comp = _splay(key);
+      }
+      _addNewRoot(_SplayTreeMapNode(key, newValue), comp);
+      return newValue;
+    }
+    throw ArgumentError.value(key, "key", "Key not in map.");
+  }
+
+  void updateAll(V update(K key, V value)) {
+    var root = _root;
+    if (root == null) return;
+    var iterator = _SplayTreeMapEntryIterator(this);
+    while (iterator.moveNext()) {
+      var node = iterator.current;
+      var newValue = update(node.key, node.value);
+      iterator._replaceValue(newValue);
+    }
+  }
+
   void addAll(Map<K, V> other) {
     other.forEach((K key, V value) {
       this[key] = value;
@@ -430,10 +491,9 @@
   bool get isNotEmpty => !isEmpty;
 
   void forEach(void f(K key, V value)) {
-    Iterator<_SplayTreeMapNode<K, V>> nodes =
-        _SplayTreeNodeIterator<K, _SplayTreeMapNode<K, V>>(this);
+    Iterator<MapEntry<K, V>> nodes = _SplayTreeMapEntryIterator<K, V>(this);
     while (nodes.moveNext()) {
-      _SplayTreeMapNode<K, V> node = nodes.current;
+      MapEntry<K, V> node = nodes.current;
       f(node.key, node.value);
     }
   }
@@ -446,9 +506,7 @@
     _clear();
   }
 
-  bool containsKey(Object? key) {
-    return _validKey(key) && _splay(key as dynamic) == 0;
-  }
+  bool containsKey(Object? key) => _containsKey(key);
 
   bool containsValue(Object? value) {
     int initialSplayCount = _splayCount;
@@ -458,10 +516,10 @@
         if (initialSplayCount != _splayCount) {
           throw ConcurrentModificationError(this);
         }
-        if (node.right != null && visit(node.right)) {
+        if (node._right != null && visit(node._right)) {
           return true;
         }
-        node = node.left;
+        node = node._left;
       }
       return false;
     }
@@ -474,6 +532,9 @@
 
   Iterable<V> get values => _SplayTreeValueIterable<K, V>(this);
 
+  Iterable<MapEntry<K, V>> get entries =>
+      _SplayTreeMapEntryIterable<K, V>(this);
+
   /// The first key in the map.
   ///
   /// Returns `null` if the map is empty.
@@ -498,12 +559,12 @@
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp < 0) return _root!.key;
-    _SplayTreeMapNode<K, V>? node = _root!.left;
+    _SplayTreeMapNode<K, V>? node = _root!._left;
     if (node == null) return null;
-    var nodeRight = node.right;
+    var nodeRight = node._right;
     while (nodeRight != null) {
       node = nodeRight;
-      nodeRight = node.right;
+      nodeRight = node._right;
     }
     return node!.key;
   }
@@ -515,12 +576,12 @@
     if (_root == null) return null;
     int comp = _splay(key);
     if (comp > 0) return _root!.key;
-    _SplayTreeMapNode<K, V>? node = _root!.right;
+    _SplayTreeMapNode<K, V>? node = _root!._right;
     if (node == null) return null;
-    var nodeLeft = node.left;
+    var nodeLeft = node._left;
     while (nodeLeft != null) {
       node = nodeLeft;
-      nodeLeft = node.left;
+      nodeLeft = node._left;
     }
     return node!.key;
   }
@@ -530,15 +591,10 @@
     implements Iterator<T> {
   final _SplayTree<K, Node> _tree;
 
-  /// Worklist of nodes to visit.
-  ///
-  /// These nodes have been passed over on the way down in a
-  /// depth-first left-to-right traversal. Visiting each node,
-  /// and their right subtrees will visit the remainder of
-  /// the nodes of a full traversal.
+  /// The current node, and all its ancestors in the tree.
   ///
   /// Only valid as long as the original tree isn't reordered.
-  final List<Node> _workList = [];
+  final List<Node> _path = [];
 
   /// Original modification counter of [_tree].
   ///
@@ -547,84 +603,76 @@
   ///
   /// Not final because some iterators may modify the tree knowingly,
   /// and they update the modification count in that case.
-  int _modificationCount;
-
-  /// Count of splay operations on [_tree] when [_workList] was built.
   ///
-  /// If the splay count on [_tree] increases, [_workList] becomes invalid.
-  int _splayCount;
+  /// Starts at `null` to represent a fresh, unstarted iterator.
+  int? _modificationCount;
 
-  /// Current node.
-  Node? _currentNode;
+  /// Count of splay operations on [_tree] when [_path] was built.
+  ///
+  /// If the splay count on [_tree] increases, [_path] becomes invalid.
+  int _splayCount;
 
   _SplayTreeIterator(_SplayTree<K, Node> tree)
       : _tree = tree,
-        _modificationCount = tree._modificationCount,
-        _splayCount = tree._splayCount {
-    _findLeftMostDescendent(tree._root);
-  }
-
-  _SplayTreeIterator.startAt(_SplayTree<K, Node> tree, K startKey)
-      : _tree = tree,
-        _modificationCount = tree._modificationCount,
-        _splayCount = -1 {
-    if (tree._root == null) return;
-    int compare = tree._splay(startKey);
-    _splayCount = tree._splayCount;
-    if (compare < 0) {
-      // Don't include the root, start at the next element after the root.
-      _findLeftMostDescendent(tree._root!.right);
-    } else {
-      _workList.add(tree._root!);
-    }
-  }
+        _splayCount = tree._splayCount;
 
   T get current {
-    var node = _currentNode;
-    if (node == null) return null as T;
+    if (_path.isEmpty) return null as T;
+    var node = _path.last;
     return _getValue(node);
   }
 
-  void _findLeftMostDescendent(Node? node) {
-    while (node != null) {
-      _workList.add(node);
-      node = node.left;
-    }
-  }
-
   /// Called when the tree structure of the tree has changed.
   ///
   /// This can be caused by a splay operation.
   /// If the key-set changes, iteration is aborted before getting
   /// here, so we know that the keys are the same as before, it's
   /// only the tree that has been reordered.
-  void _rebuildWorkList(Node currentNode) {
-    assert(_workList.isNotEmpty);
-    _workList.clear();
-    _tree._splay(currentNode.key);
-    _findLeftMostDescendent(_tree._root!.right);
-    assert(_workList.isNotEmpty);
+  void _rebuildPath(K key) {
+    _path.clear();
+    _tree._splay(key);
+    _path.add(_tree._root!);
+    _splayCount = _tree._splayCount;
+  }
+
+  void _findLeftMostDescendent(Node? node) {
+    while (node != null) {
+      _path.add(node);
+      node = node._left;
+    }
   }
 
   bool moveNext() {
     if (_modificationCount != _tree._modificationCount) {
+      if (_modificationCount == null) {
+        _modificationCount = _tree._modificationCount;
+        var node = _tree._root;
+        while (node != null) {
+          _path.add(node);
+          node = node._left;
+        }
+        return _path.isNotEmpty;
+      }
       throw ConcurrentModificationError(_tree);
     }
-    // Picks the next element in the worklist as current.
-    // Updates the worklist with the left-most path of the current node's
-    // right-hand child.
-    // If the worklist is no longer valid (after a splay), it is rebuild
-    // from scratch.
-    if (_workList.isEmpty) {
-      _currentNode = null;
-      return false;
+    if (_path.isEmpty) return false;
+    if (_splayCount != _tree._splayCount) {
+      _rebuildPath(_path.last.key);
     }
-    if (_tree._splayCount != _splayCount && _currentNode != null) {
-      _rebuildWorkList(_currentNode!);
+    var node = _path.last;
+    var next = node._right;
+    if (next != null) {
+      while (next != null) {
+        _path.add(next);
+        next = next._left;
+      }
+      return true;
     }
-    _currentNode = _workList.removeLast();
-    _findLeftMostDescendent(_currentNode!.right);
-    return true;
+    _path.removeLast();
+    while (_path.isNotEmpty && identical(_path.last._right, node)) {
+      node = _path.removeLast();
+    }
+    return _path.isNotEmpty;
   }
 
   T _getValue(Node node);
@@ -638,6 +686,8 @@
   bool get isEmpty => _tree._count == 0;
   Iterator<K> get iterator => _SplayTreeKeyIterator<K, Node>(_tree);
 
+  bool contains(Object? o) => _tree._containsKey(o);
+
   Set<K> toSet() {
     SplayTreeSet<K> set = SplayTreeSet<K>(_tree._compare, _tree._validKey);
     set._count = _tree._count;
@@ -654,6 +704,16 @@
   Iterator<V> get iterator => _SplayTreeValueIterator<K, V>(_map);
 }
 
+class _SplayTreeMapEntryIterable<K, V>
+    extends EfficientLengthIterable<MapEntry<K, V>> {
+  SplayTreeMap<K, V> _map;
+  _SplayTreeMapEntryIterable(this._map);
+  int get length => _map._count;
+  bool get isEmpty => _map._count == 0;
+  Iterator<MapEntry<K, V>> get iterator =>
+      _SplayTreeMapEntryIterator<K, V>(_map);
+}
+
 class _SplayTreeKeyIterator<K, Node extends _SplayTreeNode<K, Node>>
     extends _SplayTreeIterator<K, Node, K> {
   _SplayTreeKeyIterator(_SplayTree<K, Node> map) : super(map);
@@ -666,12 +726,36 @@
   V _getValue(_SplayTreeMapNode<K, V> node) => node.value;
 }
 
-class _SplayTreeNodeIterator<K, Node extends _SplayTreeNode<K, Node>>
-    extends _SplayTreeIterator<K, Node, Node> {
-  _SplayTreeNodeIterator(_SplayTree<K, Node> tree) : super(tree);
-  _SplayTreeNodeIterator.startAt(_SplayTree<K, Node> tree, K startKey)
-      : super.startAt(tree, startKey);
-  Node _getValue(Node node) => node;
+class _SplayTreeMapEntryIterator<K, V>
+    extends _SplayTreeIterator<K, _SplayTreeMapNode<K, V>, MapEntry<K, V>> {
+  _SplayTreeMapEntryIterator(SplayTreeMap<K, V> tree) : super(tree);
+  MapEntry<K, V> _getValue(_SplayTreeMapNode<K, V> node) => node;
+
+  // Replaces the value of the current node.
+  void _replaceValue(V value) {
+    assert(_path.isNotEmpty);
+    if (_modificationCount != _tree._modificationCount) {
+      throw ConcurrentModificationError(_tree);
+    }
+    if (_splayCount != _tree._splayCount) {
+      _rebuildPath(_path.last.key);
+    }
+    var last = _path.removeLast();
+    var newLast = last._replaceValue(value);
+    if (_path.isEmpty) {
+      _tree._root = newLast;
+    } else {
+      var parent = _path.last;
+      if (identical(last, parent._left)) {
+        parent._left = newLast;
+      } else {
+        assert(identical(last, parent._right));
+        parent._right = newLast;
+      }
+    }
+    _path.add(newLast);
+    _splayCount = ++_tree._splayCount;
+  }
 }
 
 /// A [Set] of objects that can be ordered relative to each other.
@@ -794,7 +878,9 @@
     return _validKey(element) && _splay(element as E) == 0;
   }
 
-  bool add(E element) {
+  bool add(E element) => _add(element);
+
+  bool _add(E element) {
     int compare = _splay(element);
     if (compare == 0) return false;
     _addNewRoot(_SplayTreeSetNode(element), compare);
@@ -808,10 +894,7 @@
 
   void addAll(Iterable<E> elements) {
     for (E element in elements) {
-      int compare = _splay(element);
-      if (compare != 0) {
-        _addNewRoot(_SplayTreeSetNode(element), compare);
-      }
+      _add(element);
     }
   }
 
@@ -890,17 +973,17 @@
       Node? left;
       Node? right;
       do {
-        left = node.left;
-        right = node.right;
+        left = node._left;
+        right = node._right;
         if (left != null) {
           var newLeft = _SplayTreeSetNode<E>(left.key);
-          dest.left = newLeft;
+          dest._left = newLeft;
           // Recursively copy the left tree.
           copyChildren(left, newLeft);
         }
         if (right != null) {
           var newRight = _SplayTreeSetNode<E>(right.key);
-          dest.right = newRight;
+          dest._right = newRight;
           // Set node and dest to copy the right tree iteratively.
           node = right;
           dest = newRight;
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index 9c5572c..17590cc 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -352,5 +352,5 @@
 
   const MapEntry._(this.key, this.value);
 
-  String toString() => "MapEntry(${key.toString()}: ${value.toString()})";
+  String toString() => "MapEntry($key: $value)";
 }
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 07256d4..4469213 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,19 +3,19 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript numbert
+Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
-Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
+Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Object_Identity/object_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/42222#issuecomment-640431711
-Language/Expressions/Shift/integer_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Shift/integer_t02: SkipByDesign # uses integer literal not representable as JavaScript numbert
+Language/Expressions/Shift/integer_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Shift/integer_t07: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Libraries_and_Scripts/Scripts/main_optional_parameters_t01: SkipByDesign # https://github.com/dart-lang/co19/issues/952
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
index ebc0be6..97c1673 100644
--- a/tests/co19/co19-dartdevc.status
+++ b/tests/co19/co19-dartdevc.status
@@ -52,21 +52,21 @@
 Language/Classes/Instance_Variables/definition_t02: Skip # Times out
 Language/Classes/Instance_Variables/definition_t04: Skip # Times out
 Language/Classes/Setters/instance_setter_t01: Skip # Times out
-Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript numbert
+Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out
 Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out
 Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
-Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript numbert
+Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Object_Identity/object_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/42222#issuecomment-640431711
-Language/Expressions/Shift/integer_t01: SkipByDesign # uses integer literal not representable as JavaScript numbert
-Language/Expressions/Shift/integer_t02: SkipByDesign # uses integer literal not representable as JavaScript numbert
+Language/Expressions/Shift/integer_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Shift/integer_t07: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign # dart:isolate not supported.
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # External variables are not supported
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # External variables are not supported
diff --git a/tests/corelib/splay_tree_test.dart b/tests/corelib/splay_tree_test.dart
index 6048410..9ca5cb8 100644
--- a/tests/corelib/splay_tree_test.dart
+++ b/tests/corelib/splay_tree_test.dart
@@ -28,7 +28,6 @@
   for (var v in ["first", "second", "third", "fourth", "fifth"]) {
     Expect.isTrue(tree.containsValue(v));
   }
-  ;
   Expect.isFalse(tree.containsValue("sixth"));
 
   tree[7] = "seventh";
@@ -55,6 +54,7 @@
   regressRemoveWhere();
   regressRemoveWhere2();
   regressFromCompare();
+  regressIncomparable();
 }
 
 void regressRemoveWhere() {
@@ -132,6 +132,63 @@
   Expect.equals(42, map[key(5)]);
 }
 
+// Incomparable keys throw when added, even on an empty collection.
+void regressIncomparable() {
+  var set = SplayTreeSet();
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+  set.add(1);
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+
+  var map = SplayTreeMap();
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+  map[1] = 1;
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+
+  // But not if the compare function allows them.
+  // This now includes `null`.
+  int compare(Object? o1, Object? o2) {
+    if (o1 == null) return o2 == null ? 0 : -1;
+    if (o2 == null) return 1;
+    if (o1 is IncomparableKey && o2 is IncomparableKey) {
+      return o1.id - o2.id;
+    }
+    throw UnsupportedError("Nope");
+  }
+  for (var key in [null, IncomparableKey(0)]) {
+    set = SplayTreeSet<Object?>(compare);
+    set.add(key);
+    Expect.equals(1, set.length);
+    set.clear();
+    Expect.isNull(set.lookup(key));
+    set.clear();
+    set.add(IncomparableKey(1));
+    set.add(key);
+    Expect.identical(key, set.first);
+    Expect.identical(key, set.lookup(key));
+
+    map = SplayTreeMap<Object?, Object?>(compare);
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map[IncomparableKey(1)] = 0;
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+  }
+}
+
 class IncomparableKey {
   final int id;
   IncomparableKey(this.id);
diff --git a/tests/corelib_2/splay_tree_test.dart b/tests/corelib_2/splay_tree_test.dart
index 6048410..807d700 100644
--- a/tests/corelib_2/splay_tree_test.dart
+++ b/tests/corelib_2/splay_tree_test.dart
@@ -28,7 +28,6 @@
   for (var v in ["first", "second", "third", "fourth", "fifth"]) {
     Expect.isTrue(tree.containsValue(v));
   }
-  ;
   Expect.isFalse(tree.containsValue("sixth"));
 
   tree[7] = "seventh";
@@ -55,6 +54,7 @@
   regressRemoveWhere();
   regressRemoveWhere2();
   regressFromCompare();
+  regressIncomparable();
 }
 
 void regressRemoveWhere() {
@@ -132,6 +132,63 @@
   Expect.equals(42, map[key(5)]);
 }
 
+// Incomparable keys throw when added, even on an empty collection.
+void regressIncomparable() {
+  var set = SplayTreeSet();
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+  set.add(1);
+  Expect.throws(() => set.add(IncomparableKey(0)));
+  Expect.throws(() => set.lookup(IncomparableKey(0)));
+
+  var map = SplayTreeMap();
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+  map[1] = 1;
+  Expect.throws(() => map[IncomparableKey(0)] = 0);
+  Expect.throws(() => map.putIfAbsent(IncomparableKey(0), () => 0));
+
+  // But not if the compare function allows them.
+  // This now includes `null`.
+  int compare(Object o1, Object o2) {
+    if (o1 == null) return o2 == null ? 0 : -1;
+    if (o2 == null) return 1;
+    if (o1 is IncomparableKey && o2 is IncomparableKey) {
+      return o1.id - o2.id;
+    }
+    throw UnsupportedError("Nope");
+  }
+  for (var key in [null, IncomparableKey(0)]) {
+    set = SplayTreeSet<Object>(compare);
+    set.add(key);
+    Expect.equals(1, set.length);
+    set.clear();
+    Expect.isNull(set.lookup(key));
+    set.clear();
+    set.add(IncomparableKey(1));
+    set.add(key);
+    Expect.identical(key, set.first);
+    Expect.identical(key, set.lookup(key));
+
+    map = SplayTreeMap<Object, Object>(compare);
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.clear();
+    map[IncomparableKey(1)] = 0;
+    map[key] = 0;
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+    map.putIfAbsent(key, () => 0);
+    Expect.isTrue(map.containsKey(key));
+    map.remove(key);
+    Expect.isFalse(map.containsKey(key));
+  }
+}
+
 class IncomparableKey {
   final int id;
   IncomparableKey(this.id);
diff --git a/tests/language/deferred/inheritance_constraints_test.dart b/tests/language/deferred/inheritance_constraints_test.dart
index 2d9429b..7477a57 100644
--- a/tests/language/deferred/inheritance_constraints_test.dart
+++ b/tests/language/deferred/inheritance_constraints_test.dart
@@ -11,17 +11,17 @@
 
 class A extends lib.Foo {}
 //              ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.EXTENDS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class B implements lib.Foo {}
 //                 ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class C1 {}
 
 class C = C1 with lib.Foo;
 //                ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class D {
   D();
diff --git a/tests/language/deferred/load_constants_test.dart b/tests/language/deferred/load_constants_test.dart
index a57e24c..546b038 100644
--- a/tests/language/deferred/load_constants_test.dart
+++ b/tests/language/deferred/load_constants_test.dart
@@ -28,31 +28,31 @@
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.funtype]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.toplevel]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C.staticfun]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
 
     asyncEnd();
diff --git a/tests/language/generic/generic_function_type_argument_test.dart b/tests/language/generic/generic_function_type_argument_test.dart
index c51c674..c54516f 100644
--- a/tests/language/generic/generic_function_type_argument_test.dart
+++ b/tests/language/generic/generic_function_type_argument_test.dart
@@ -28,7 +28,7 @@
 typedef FB<T extends F> = S Function<S extends T>(S);
 
 // For a class:
-class CB<T extends F> {
+class CB<T extends FB<F>> {
   final T function;
   const CB(this.function);
 }
diff --git a/tests/language_2/deferred/inheritance_constraints_test.dart b/tests/language_2/deferred/inheritance_constraints_test.dart
index 2d9429b..7477a57 100644
--- a/tests/language_2/deferred/inheritance_constraints_test.dart
+++ b/tests/language_2/deferred/inheritance_constraints_test.dart
@@ -11,17 +11,17 @@
 
 class A extends lib.Foo {}
 //              ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.EXTENDS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class B implements lib.Foo {}
 //                 ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.IMPLEMENTS_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class C1 {}
 
 class C = C1 with lib.Foo;
 //                ^^^^^^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_DEFERRED_CLASS
+// [analyzer] COMPILE_TIME_ERROR.SUBTYPE_OF_DEFERRED_CLASS
 
 class D {
   D();
diff --git a/tests/language_2/deferred/load_constants_test.dart b/tests/language_2/deferred/load_constants_test.dart
index a57e24c..546b038 100644
--- a/tests/language_2/deferred/load_constants_test.dart
+++ b/tests/language_2/deferred/load_constants_test.dart
@@ -28,31 +28,31 @@
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.funtype]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.toplevel]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
     Expect.throws(() => const [foo.C.staticfun]);
     //                  ^
     // [cfe] Constant evaluation error:
     //                         ^^^^^^^^^^^^^^^
-    // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    // [analyzer] COMPILE_TIME_ERROR.COLLECTION_ELEMENT_FROM_DEFERRED_LIBRARY
     // [cfe] 'foo' can't be used in a constant expression because it's marked as 'deferred' which means it isn't available until loaded.
 
     asyncEnd();
diff --git a/tools/VERSION b/tools/VERSION
index 654aa33..5bfccf5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 158
+PRERELEASE 159
 PRERELEASE_PATCH 0
\ No newline at end of file