Version 2.19.0-37.0.dev

Merge commit 'a8be1c1e0b3452c0135c21c771c7d7f73ca45ec7' into 'dev'
diff --git a/DEPS b/DEPS
index e2150e6..73a6042 100644
--- a/DEPS
+++ b/DEPS
@@ -81,7 +81,7 @@
   "args_rev": "73e8d3b55cbedc9765f8e266f3422d8914f8e62a",
   "async_rev": "f3ed5f690e2ec9dbe1bfc5184705575b4f6480e5",
   "bazel_worker_rev": "9710de6c9c70b1b583183db9d9721ba64e5a16fe",
-  "benchmark_harness_rev": "4183c76739ed7a27c260ca9ebaab6e0f210d1a37",
+  "benchmark_harness_rev": "6a116758f2b96e92659194bcda990f42106a01d3",
   "boolean_selector_rev": "1d3565e2651d16566bb556955b96ea75018cbd0c",
   "boringssl_gen_rev": "ced85ef0a00bbca77ce5a91261a5f2ae61b1e62f",
   "boringssl_rev": "87f316d7748268eb56f2dc147bd593254ae93198",
@@ -112,22 +112,22 @@
   "devtools_rev": "95d292626da26505b02417735f77e8922783b477",
   "ffi_rev": "18b2b549d55009ff594600b04705ff6161681e07",
   "file_rev": "0132eeedea2933513bf230513a766a8baeab0c4f",
-  "fixnum_rev": "164712f6547cdfb2709b752188186baf31fd1730",
+  "fixnum_rev": "e0b17cc1f639c55a9c24947392c64b5a68992535",
   "glob_rev": "1d51fcc172e5adfbae6e82c3f8f119774cb2fca2",
   "html_rev": "8243e967caad9932c13971af3b2a7c8f028383d5",
   "http_multi_server_rev": "20bf079c8955d1250a45afb9cb096472a724a551",
-  "http_parser_rev": "eaa63304c333316acd114e3be7ed701d7d7ba32c",
-  "http_rev": "843c5ecb1ea2233ba7b7049833b5801b149fba86",
+  "http_parser_rev": "d25b3c9e7f23e31ac388a03361737110768597f6",
+  "http_rev": "5055b684ae45fb141a106ef6ced988aa37ed0ea6",
   "icu_rev": "81d656878ec611cb0b42d52c82e9dae93920d9ba",
-  "intl_rev": "e9b573679de5e703d89a242b9dca331c772979ef",
+  "intl_rev": "64dccc499162bebecb1ee29dc994f3e0c1416e96",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "805e6536dd961d66f6b8cd46d8f3e61774f957c9",
   "linter_rev": "b4afc10055f3009478da1eac1827f9fef42c3759", # 1.26.0
   "lints_rev": "8294e5648ab49474541527e2911e72e4c5aefe55",
-  "logging_rev": "f6979e3bc3b6e1847a08335b7eb6304e18986195",
+  "logging_rev": "d10e24844c2e01d3f6d2b5a1a2bb8717359c6a87",
   "markdown_rev": "e3f4bd28c9e61b522f75f291d4d6cfcfeccd83ee", # b/236358256
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
-  "matcher_rev": "1a7fcae0d7af1604781afabe61fd35d9b404d8ed",
+  "matcher_rev": "cba63ebf8ed1daeffd5f3c55fd30085152c4512d",
   "mime_rev": "0a75a41445eb642674a0a271eecde78cb025ee60",
   "mockito_rev": "d8a2ddd2054390bd03d34bf64c940884e6f7a596",
   "oauth2_rev": "199ebf15cbd5b07958438184f32e41c4447a57bf",
@@ -135,33 +135,33 @@
   "path_rev": "9955b27b9bb98d87591208e19eb01c51d29fd467",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_rev": "fa84ddd0e39f45bf3f09dcc5d6b9fbdda7820fef",
-  "protobuf_rev": "14c9c0b2d5542e73198a98054d93f0cb4acc846a",
+  "protobuf_rev": "a840335449e6a2a9617d2ebe5ecd0d577e071248",
   "pub_rev": "9bf4289d6fd5d6872a8929d6312bbd7098f3ea9c", # manually rev'd
   "pub_semver_rev": "5c0b4bfd5ca57fe16f1319c581dc8c882e9b8cb2",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
-  "shelf_rev": "f2cca46bdeb9888f29e685626bbe40654e1ca296",
+  "shelf_rev": "9dab94469d50e89a6e4e2c0086b717bddb0bf78a",
   "source_map_stack_trace_rev": "72dbf21a33293b2b8434d0a9751e36f9463981ac",
   "source_maps_rev": "e93565b43a7b6b367789de8ffba969c4ebeeb317",
   "source_span_rev": "ff03af16474ce91c89eb3bc28182866f4cb6dfb0",
-  "sse_rev": "2df072848a6090d3ed67f30c69e86ec4d6b96cd6",
+  "sse_rev": "00084c43684ddaf7e09c19c5364c4a27eb04efda",
   "stack_trace_rev": "17f09c2c6845bb31c7c385acecce5befb8527a13",
   "stream_channel_rev": "8e0d7ef1f4a3fb97fbd82e11cd539093f58511f3",
-  "string_scanner_rev": "c637deb8d998b72a5807afbd06aba8370db725c0",
+  "string_scanner_rev": "2d84b16d8ae03c3a8c2417b71abe0fe6de7d8bf6",
   "sync_http_rev": "39509d69fd5a9c3da46eab48fcafdf62e6ad4580",
-  "term_glyph_rev": "741efdedf9da62ee66a06c295d36fa28f8780e24",
-  "test_descriptor_rev": "5ed5d7f6bf1191592995dcb8eedbbc17df69d386",
+  "term_glyph_rev": "ec7cf7bb51ebb7d55760a1359f6697690dbc06ba",
+  "test_descriptor_rev": "c21e15daa3a22a7066f081d4d30aa5cae8b5de36",
   "test_process_rev": "3e695bcfeab551473ddc288970f345f30e5e1375",
   "test_reflective_loader_rev": "8d0de01bbe852fea1f8e33aba907abcba50a8a1e",
-  "test_rev": "1ae207e51c0bcc6f539d878f9f7333ad977f38e5",
+  "test_rev": "b144a336776eaa1f9420f3ab38214d8c061c663e",
   "typed_data_rev": "bb10b64f9a56b8fb49307d4465474bf1c1309f6d",
   "usage_rev": "e287a72228974886d8a3b40ddcdf12f69d7c6a22",
-  "vector_math_rev": "cdcee487bde4353a6ba7a29bfc7db3840426e50f",
+  "vector_math_rev": "09ba4fa74e668177211f917a1c14789cd05d3cab",
   "watcher_rev": "e00c0ea769e32821d91c0880da8eb736839a6e6d",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_rev": "99dbdc5769e19b9eeaf69449a59079153c6a8b1f",
   "WebCore_rev": "bcb10901266c884e7b3740abc597ab95373ab55c",
-  "webdev_rev": "3d2ad34a5354cfb2324d155d903b26590d79bd19",
+  "webdev_rev": "27cc5c9228ca59e721bc41fe7028e0fd6b995748",
   "webdriver_rev": "e1a9ad671ee82e05eee463f922a34585ed2d2f15",
   "webkit_inspection_protocol_rev": "57522d6b29d94903b765c757079d906555d5a171",
   "yaml_edit_rev": "01589b3ce447b03aed991db49f1ec6445ad5476d",
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 4c7ca36..3c57d35 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -114,7 +114,7 @@
   int contextBuilds = 0;
 
   /// The subscription to the stream of incoming messages from the client.
-  late StreamSubscription<void> _channelSubscription;
+  late final StreamSubscription<void> _channelSubscription;
 
   /// A completer that tracks in-progress analysis context rebuilds.
   ///
@@ -440,7 +440,7 @@
     _channelSubscription.pause(completer.future);
 
     try {
-      // `await` here is imported to ensure `finally` doesn't execute until
+      // `await` here is important to ensure `finally` doesn't execute until
       // `operation()` completes (`whenComplete` is not available on
       // `FutureOr`).
       return await operation();
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index bc19b76..f571ee9 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -96,7 +96,7 @@
     } else if (node is InstanceCreationExpression) {
       properties['static type'] = node.staticType;
     } else if (node is LibraryDirective) {
-      properties['element'] = node.element;
+      properties['element'] = node.element2;
     } else if (node is MethodDeclaration) {
       properties['declaredElement'] = node.declaredElement;
       properties['external keyword'] = node.externalKeyword;
@@ -107,10 +107,10 @@
       properties['static invoke type'] = node.staticInvokeType;
       properties['static type'] = node.staticType;
     } else if (node is PartDirective) {
-      properties['element'] = node.element;
+      properties['element'] = node.element2;
       properties['uriSource'] = node.uriSource;
     } else if (node is PartOfDirective) {
-      properties['element'] = node.element;
+      properties['element'] = node.element2;
     } else if (node is PostfixExpression) {
       properties['static element'] = node.staticElement;
       properties['static type'] = node.staticType;
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f7cf1fc..e16c1b4 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -4,6 +4,7 @@
 * Deprecated `ClassOrMixinDeclaration.getField`, filter `members` instead.
 * Deprecated `ClassOrMixinDeclaration.getMethod`, filter `members` instead.
 * Deprecated `ClassDeclaration.getConstructor`, filter `members` instead.
+* Deprecated `Directive.element`, use `element2` instead.
 
 ## 4.3.1
 * Fix `identifier` for `LibraryExportElement` and `LibraryImportElement`.
diff --git a/pkg/analyzer/lib/dart/analysis/utilities.dart b/pkg/analyzer/lib/dart/analysis/utilities.dart
index 64dfab7..89d8322 100644
--- a/pkg/analyzer/lib/dart/analysis/utilities.dart
+++ b/pkg/analyzer/lib/dart/analysis/utilities.dart
@@ -28,14 +28,14 @@
 /// query it to get an [AnalysisSession], and then call `getParsedUnit`.
 ///
 /// Callers that don't need the feature set to be strictly correct can pass in
-/// `FeatureSet.fromEnableFlags([])` to enable the default set of features; this
-/// is much more performant than using an analysis session, because it doesn't
-/// require the analyzer to process the SDK.
+/// `FeatureSet.latestLanguageVersion()` to enable the default set of features;
+/// this is much more performant than using an analysis session, because it
+/// doesn't require the analyzer to process the SDK.
 ///
 /// If [throwIfDiagnostics] is `true` (the default), then if any diagnostics are
-/// produced because of syntactic errors in the [content] an `ArgumentError`
-/// will be thrown. If the parameter is `false`, then the caller can check the
-/// result to see whether there are any errors.
+/// produced because of syntactic errors in the file an `ArgumentError` will be
+/// thrown. If the parameter is `false`, then the caller can check the result
+/// to see whether there are any errors.
 ParseStringResult parseFile(
     {required String path,
     ResourceProvider? resourceProvider,
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 74bd94d..fc24d3d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -630,8 +630,7 @@
   /// The token representing the 'augment' keyword.
   Token get augmentKeyword;
 
-  /// Return the element associated with this directive, or `null` if the AST
-  /// structure has not been resolved.
+  @Deprecated('Use element2 instead')
   @override
   AugmentationImportElement? get element;
 
@@ -1526,8 +1525,13 @@
   /// Return the element associated with this directive, or `null` if the AST
   /// structure has not been resolved or if this directive could not be
   /// resolved.
+  @Deprecated('Use element2 instead')
   Element? get element;
 
+  /// Return the element associated with this directive, or `null` if the AST
+  /// structure has not been resolved.
+  Element? get element2;
+
   /// Return the token representing the keyword that introduces this directive
   /// ('import', 'export', 'library' or 'part').
   @Deprecated('Use specific xyzToken instead')
@@ -1714,6 +1718,7 @@
 
   /// Return the element associated with this directive, or `null` if the AST
   /// structure has not been resolved.
+  @override
   LibraryExportElement? get element2;
 
   /// The token representing the 'export' keyword.
@@ -2893,6 +2898,7 @@
 
   /// Return the element associated with this directive, or `null` if the AST
   /// structure has not been resolved.
+  @override
   LibraryImportElement? get element2;
 
   /// The token representing the 'import' keyword.
@@ -3644,6 +3650,9 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class PartDirective implements UriBasedDirective {
+  @override
+  PartElement? get element2;
+
   /// Return the token representing the 'part' keyword.
   Token get partKeyword;
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 7ea2d0c..265798f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -793,7 +793,7 @@
 
   @override
   void visitPartDirective(PartDirective node) {
-    final partElement = node.element;
+    final partElement = node.element2;
     if (partElement is PartElement) {
       final partElementUri = partElement.uri;
       if (partElementUri is DirectiveUriWithUnit) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 3eb1e38..b0ad4c6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -590,7 +590,7 @@
       if (unitResult is ResolvedUnitResult) {
         CompilationUnit unit = unitResult.unit;
         for (Directive directive in unit.directives) {
-          if (directive is PartOfDirective && directive.element == element) {
+          if (directive is PartOfDirective && directive.element2 == element) {
             results.add(
               SearchResult._(
                 unit.declaredElement!,
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 00f3d6b..2c88c82 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -902,9 +902,15 @@
     _becomeParentOf(_uri);
   }
 
+  @Deprecated('Use element2 instead')
   @override
   AugmentationImportElement? get element {
-    return super.element as AugmentationImportElement?;
+    throw StateError('Use element2 instead');
+  }
+
+  @override
+  AugmentationImportElement? get element2 {
+    return super.element2 as AugmentationImportElement?;
   }
 
   @override
@@ -919,7 +925,7 @@
 
   @override
   LibraryAugmentationElement? get uriElement {
-    return element?.importedAugmentation;
+    return element2?.importedAugmentation;
   }
 
   @override
@@ -3274,6 +3280,7 @@
   /// attribute.
   DirectiveImpl(super.comment, super.metadata);
 
+  @Deprecated('Use element2 instead')
   @override
   Element? get element => _element;
 
@@ -3281,6 +3288,9 @@
   set element(Element? element) {
     _element = element;
   }
+
+  @override
+  Element? get element2 => _element;
 }
 
 /// A do statement.
@@ -3799,7 +3809,7 @@
   }
 
   @override
-  LibraryExportElement? get element2 => super.element as LibraryExportElement?;
+  LibraryExportElement? get element2 => super.element2 as LibraryExportElement?;
 
   @override
   Token get firstTokenAfterCommentAndMetadata => exportKeyword;
@@ -6449,7 +6459,7 @@
   }
 
   @override
-  LibraryImportElement? get element2 => super.element as LibraryImportElement?;
+  LibraryImportElement? get element2 => super.element2 as LibraryImportElement?;
 
   @override
   Token get firstTokenAfterCommentAndMetadata => importKeyword;
@@ -8796,6 +8806,11 @@
       : super(comment, metadata, partUri);
 
   @override
+  PartElement? get element2 {
+    return super.element2 as PartElement?;
+  }
+
+  @override
   Token get endToken => semicolon;
 
   @override
@@ -8807,8 +8822,7 @@
 
   @override
   CompilationUnitElement? get uriElement {
-    final partElement = element as PartElement?;
-    final partElementUri = partElement?.uri;
+    final partElementUri = element2?.uri;
     if (partElementUri is DirectiveUriWithUnit) {
       return partElementUri.unit;
     }
diff --git a/pkg/analyzer/lib/src/dart/ast/element_locator.dart b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
index 8f676e4..279c3fb 100644
--- a/pkg/analyzer/lib/src/dart/ast/element_locator.dart
+++ b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
@@ -98,12 +98,12 @@
     } else if (parent is LibraryIdentifier) {
       var grandParent = parent.parent;
       if (grandParent is PartOfDirective) {
-        var element = grandParent.element;
+        var element = grandParent.element2;
         if (element is LibraryElement) {
           return element.definingCompilationUnit;
         }
       } else if (grandParent is LibraryDirective) {
-        return grandParent.element;
+        return grandParent.element2;
       }
     }
     return node.writeOrReadElement;
@@ -126,7 +126,7 @@
 
   @override
   Element? visitLibraryDirective(LibraryDirective node) {
-    return node.element;
+    return node.element2;
   }
 
   @override
@@ -141,7 +141,7 @@
 
   @override
   Element? visitPartOfDirective(PartOfDirective node) {
-    return node.element;
+    return node.element2;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 5cea4ce..ed87486 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -151,7 +151,7 @@
 
   @override
   void visitAugmentationImportDirective(AugmentationImportDirective node) {
-    final element = node.element;
+    final element = node.element2;
     if (element is AugmentationImportElementImpl) {
       _setOrCreateMetadataElements(element, node.metadata);
     }
@@ -828,7 +828,7 @@
 
   @override
   void visitLibraryAugmentationDirective(LibraryAugmentationDirective node) {
-    final element = node.element;
+    final element = node.element2;
     if (element is LibraryOrAugmentationElementImpl) {
       _setOrCreateMetadataElements(element, node.metadata);
     }
@@ -841,7 +841,7 @@
   @override
   void visitLibraryDirective(LibraryDirective node) {
     ++_libraryDirectiveIndex;
-    var element = node.element;
+    var element = node.element2;
     if (element is LibraryElementImpl && _libraryDirectiveIndex == 1) {
       _setOrCreateMetadataElements(element, node.metadata);
     }
@@ -924,8 +924,8 @@
 
   @override
   void visitPartDirective(PartDirective node) {
-    var element = node.element;
-    if (element is CompilationUnitElementImpl) {
+    var element = node.element2;
+    if (element is PartElementImpl) {
       _setOrCreateMetadataElements(element, node.metadata);
     }
 
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 08a40f1..08751df 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -70,7 +70,7 @@
         _container.documentationComment = getCommentNodeRawText(
           firstDirective.documentationComment,
         );
-        var firstDirectiveMetadata = firstDirective.element?.metadata;
+        var firstDirectiveMetadata = firstDirective.element2?.metadata;
         if (firstDirectiveMetadata != null) {
           _container.metadata = firstDirectiveMetadata;
         }
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index fb9ae05..b382aee 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -135,7 +135,7 @@
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    _checkResolved(node, node.element, (node) => node is LibraryElement);
+    _checkResolved(node, node.element2, (node) => node is LibraryElement);
   }
 
   @override
@@ -146,12 +146,12 @@
   @override
   void visitPartDirective(PartDirective node) {
     _checkResolved(
-        node, node.element, (node) => node is CompilationUnitElement);
+        node, node.element2, (node) => node is CompilationUnitElement);
   }
 
   @override
   void visitPartOfDirective(PartOfDirective node) {
-    _checkResolved(node, node.element, (node) => node is LibraryElement);
+    _checkResolved(node, node.element2, (node) => node is LibraryElement);
   }
 
   @override
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 3139dc0..d1c30e3 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -129,7 +129,7 @@
     _writeln('AugmentationImportDirective');
     _withIndent(() {
       _writeNamedChildEntities(node);
-      _writeElement('element', node.element);
+      _writeElement('element', node.element2);
       _writeRaw('uriContent', node.uriContent);
       _writeElement('uriElement', node.uriElement);
       _writeSource('uriSource', node.uriSource);
@@ -774,7 +774,7 @@
     _writeln('LibraryAugmentationDirective');
     _withIndent(() {
       _writeNamedChildEntities(node);
-      _writeElement('element', node.element);
+      _writeElement('element', node.element2);
     });
   }
 
@@ -783,7 +783,7 @@
     _writeln('LibraryDirective');
     _withIndent(() {
       _writeNamedChildEntities(node);
-      _writeElement('element', node.element);
+      _writeElement('element', node.element2);
     });
   }
 
@@ -901,7 +901,7 @@
     _writeln('PartDirective');
     _withIndent(() {
       _writeNamedChildEntities(node);
-      _writeElement('element', node.element);
+      _writeElement('element', node.element2);
       _writeRaw('uriContent', node.uriContent);
       _writePartUnitElement('uriElement', node.uriElement);
       _writeSource('uriSource', node.uriSource);
@@ -913,7 +913,7 @@
     _writeln('PartOfDirective');
     _withIndent(() {
       _writeNamedChildEntities(node);
-      _writeElement('element', node.element);
+      _writeElement('element', node.element2);
     });
   }
 
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index c58c3e2..d0b8b44 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -385,12 +385,12 @@
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    computer._addRegionForNode(node.name, node.element);
+    computer._addRegionForNode(node.name, node.element2);
   }
 
   @override
   void visitPartDirective(PartDirective node) {
-    final element = node.element;
+    final element = node.element2;
     if (element is PartElement) {
       final uri = element.uri;
       if (uri is DirectiveUriWithUnit) {
@@ -413,7 +413,7 @@
 
   @override
   void visitPartOfDirective(PartOfDirective node) {
-    computer._addRegionForNode(node.libraryName ?? node.uri, node.element);
+    computer._addRegionForNode(node.libraryName ?? node.uri, node.element2);
     super.visitPartOfDirective(node);
   }
 
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart
index 2d2a59a..70df2ad 100644
--- a/pkg/dart2wasm/lib/constants.dart
+++ b/pkg/dart2wasm/lib/constants.dart
@@ -826,4 +826,20 @@
       });
     }
   }
+
+  @override
+  ConstantInfo? visitSymbolConstant(SymbolConstant constant) {
+    ClassInfo info = translator.classInfo[translator.symbolClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.RefType stringType =
+        translator.classInfo[translator.coreTypes.stringClass]!.nonNullableType;
+    StringConstant nameConstant = StringConstant(constant.name);
+    ensureConstant(nameConstant);
+    return createConstant(constant, info.nonNullableType, (function, b) {
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      constants.instantiateConstant(function, b, nameConstant, stringType);
+      translator.struct_new(b, info);
+    });
+  }
 }
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
index fb50aec..dc57e39 100644
--- a/pkg/dart2wasm/lib/translator.dart
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -112,6 +112,7 @@
   late final Class byteDataViewClass;
   late final Class typeErrorClass;
   late final Class typeUniverseClass;
+  late final Class symbolClass;
   late final Procedure wasmFunctionCall;
   late final Procedure wasmTableCallIndirect;
   late final Procedure stackTraceCurrent;
@@ -188,6 +189,7 @@
     Class Function(String) lookupCore = makeLookup("dart.core");
     Class Function(String) lookupCollection = makeLookup("dart.collection");
     Class Function(String) lookupFfi = makeLookup("dart.ffi");
+    Class Function(String) lookupInternal = makeLookup("dart._internal");
     Class Function(String) lookupTypedData = makeLookup("dart.typed_data");
     Class Function(String) lookupWasm = makeLookup("dart.wasm");
 
@@ -235,6 +237,7 @@
     typedListClass = lookupTypedData("_TypedList");
     typedListViewClass = lookupTypedData("_TypedListView");
     byteDataViewClass = lookupTypedData("_ByteDataView");
+    symbolClass = lookupInternal("Symbol");
     wasmFunctionCall =
         wasmFunctionClass.procedures.firstWhere((p) => p.name.text == "call");
     wasmTableCallIndirect = wasmTableClass.procedures
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index 78cb595..14cc87c 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -330,6 +330,7 @@
     if (s->kind() != Snapshot::kFullAOT) {
       s->WriteTokenPosition(cls->untag()->token_pos_);
       s->WriteTokenPosition(cls->untag()->end_token_pos_);
+      s->WriteCid(cls->untag()->implementor_cid_);
     }
     s->Write<uint32_t>(cls->untag()->state_bits_);
 
@@ -426,6 +427,7 @@
       ASSERT(d_->kind() != Snapshot::kFullAOT);
       cls->untag()->token_pos_ = d.ReadTokenPosition();
       cls->untag()->end_token_pos_ = d.ReadTokenPosition();
+      cls->untag()->implementor_cid_ = d.ReadCid();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
       cls->untag()->state_bits_ = d.Read<uint32_t>();
 
@@ -469,6 +471,7 @@
       ASSERT(d_->kind() != Snapshot::kFullAOT);
       cls->untag()->token_pos_ = d.ReadTokenPosition();
       cls->untag()->end_token_pos_ = d.ReadTokenPosition();
+      cls->untag()->implementor_cid_ = d.ReadCid();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
       cls->untag()->state_bits_ = d.Read<uint32_t>();
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 141ae5a..bd47dc0 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -302,6 +302,7 @@
                  err.ToErrorCString());
     OS::Exit(255);
   }
+
   if (FLAG_trace_class_finalization) {
     OS::PrintErr("VerifyBootstrapClasses END.\n");
   }
@@ -1091,7 +1092,7 @@
 
   // Add this class as an implementor to the implemented interface's type
   // classes.
-  const auto& interfaces = Array::Handle(zone, cls.interfaces());
+  auto& interfaces = Array::Handle(zone, cls.interfaces());
   const intptr_t mixin_index =
       cls.is_transformed_mixin_application() ? interfaces.Length() - 1 : -1;
   for (intptr_t i = 0; i < interfaces.Length(); ++i) {
@@ -1100,6 +1101,25 @@
     MarkImplemented(zone, other_cls);
     other_cls.AddDirectImplementor(cls, /* is_mixin = */ i == mixin_index);
   }
+
+  // Propogate known concrete implementors to interfaces.
+  if (!cls.is_abstract()) {
+    GrowableArray<const Class*> worklist;
+    worklist.Add(&cls);
+    while (!worklist.is_empty()) {
+      const Class& implemented = *worklist.RemoveLast();
+      if (!implemented.NoteImplementor(cls)) continue;
+      type = implemented.super_type();
+      if (!type.IsNull()) {
+        worklist.Add(&Class::Handle(zone, implemented.SuperClass()));
+      }
+      interfaces = implemented.interfaces();
+      for (intptr_t i = 0; i < interfaces.Length(); i++) {
+        type ^= interfaces.At(i);
+        worklist.Add(&Class::Handle(zone, type.type_class()));
+      }
+    }
+  }
 }
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
@@ -1493,6 +1513,7 @@
         return;
       }
       cls->untag()->id_ = Map(old_cid);
+      cls->untag()->implementor_cid_ = Map(cls->untag()->implementor_cid_);
     } else if (obj->IsField()) {
       FieldPtr field = Field::RawCast(obj);
       field->untag()->guarded_cid_ = Map(field->untag()->guarded_cid_);
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index c1488d8..526a2c8 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -108,12 +108,13 @@
   }
 
   const Class& cls = Class::Handle(Z, target_function.Owner());
-  if (CHA::IsImplemented(cls) || CHA::HasSubclasses(cls)) {
+  intptr_t implementor_cid = kIllegalCid;
+  if (!CHA::HasSingleConcreteImplementation(cls, &implementor_cid)) {
     return false;
   }
 
   call->SetTargets(
-      CallTargets::CreateMonomorphic(Z, cls.id(), target_function));
+      CallTargets::CreateMonomorphic(Z, implementor_cid, target_function));
   ASSERT(call->Targets().IsMonomorphic());
 
   // If we know that the only noSuchMethod is Object.noSuchMethod then
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 086e3e5..b9804d5 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -768,38 +768,12 @@
       cid_ = kSentinelCid;
     } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
       cid_ = kClosureCid;
-    } else if (type_->IsDoubleType()) {
-      cid_ = kDoubleCid;  // double's only implementor is _Double.
-    } else if (type_->IsFloat32x4Type()) {
-      cid_ = kFloat32x4Cid;  // Float32x4's only implementor is _Float32x4.
-    } else if (type_->IsFloat64x2Type()) {
-      cid_ = kFloat64x2Cid;  // Float64x2's only implementor is _Float64x2.
-    } else if (type_->IsInt32x4Type()) {
-      cid_ = kInt32x4Cid;  // Int32x4's only implementor is _Int32x4.
     } else if (type_->type_class_id() != kIllegalCid) {
       const Class& type_class = Class::Handle(type_->type_class());
-      Thread* thread = Thread::Current();
-      CHA& cha = thread->compiler_state().cha();
-      // Don't infer a cid from an abstract type since there can be multiple
-      // compatible classes with different cids.
-      if (!type_class.is_abstract() && !CHA::IsImplemented(type_class) &&
-          !CHA::HasSubclasses(type_class)) {
-        if (type_class.IsPrivate()) {
-          // Type of a private class cannot change through later loaded libs.
-          cid_ = type_class.id();
-        } else if (FLAG_use_cha_deopt ||
-                   thread->isolate_group()->all_classes_finalized()) {
-          if (FLAG_trace_cha) {
-            THR_Print("  **(CHA) Compile type not subclassed: %s\n",
-                      type_class.ToCString());
-          }
-          if (FLAG_use_cha_deopt) {
-            cha.AddToGuardedClasses(type_class, /*subclass_count=*/0);
-          }
-          cid_ = type_class.id();
-        } else {
-          cid_ = kDynamicCid;
-        }
+      intptr_t implementation_cid = kIllegalCid;
+      if (CHA::HasSingleConcreteImplementation(type_class,
+                                               &implementation_cid)) {
+        cid_ = implementation_cid;
       } else {
         cid_ = kDynamicCid;
       }
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index ae363e2..7831f36 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -1102,39 +1102,20 @@
 }
 
 // Returns true if checking against this type is a direct class id comparison.
-bool CallSpecializer::TypeCheckAsClassEquality(const AbstractType& type) {
+bool CallSpecializer::TypeCheckAsClassEquality(const AbstractType& type,
+                                               intptr_t* type_cid) {
+  *type_cid = kIllegalCid;
   ASSERT(type.IsFinalized());
   // Requires CHA.
   if (!type.IsInstantiated()) return false;
   // Function types have different type checking rules.
   if (type.IsFunctionType()) return false;
+
   const Class& type_class = Class::Handle(type.type_class());
-  // Could be an interface check?
-  if (CHA::IsImplemented(type_class)) return false;
-  // Check if there are subclasses.
-  if (CHA::HasSubclasses(type_class)) {
+  if (!CHA::HasSingleConcreteImplementation(type_class, type_cid)) {
     return false;
   }
 
-  // Private classes cannot be subclassed by later loaded libs.
-  if (!type_class.IsPrivate()) {
-    // In AOT mode we can't use CHA deoptimizations.
-    ASSERT(!CompilerState::Current().is_aot() || !FLAG_use_cha_deopt);
-    if (FLAG_use_cha_deopt || isolate_group()->all_classes_finalized()) {
-      if (FLAG_trace_cha) {
-        THR_Print(
-            "  **(CHA) Typecheck as class equality since no "
-            "subclasses: %s\n",
-            type_class.ToCString());
-      }
-      if (FLAG_use_cha_deopt) {
-        thread()->compiler_state().cha().AddToGuardedClasses(
-            type_class, /*subclass_count=*/0);
-      }
-    } else {
-      return false;
-    }
-  }
   const intptr_t num_type_args = type_class.NumTypeArguments();
   if (num_type_args > 0) {
     // Only raw types can be directly compared, thus disregarding type
@@ -1242,10 +1223,10 @@
     return;
   }
 
-  if (TypeCheckAsClassEquality(type)) {
+  intptr_t type_cid;
+  if (TypeCheckAsClassEquality(type, &type_cid)) {
     LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left));
     InsertBefore(call, left_cid, NULL, FlowGraph::kValue);
-    const intptr_t type_cid = Class::Handle(Z, type.type_class()).id();
     ConstantInstr* cid =
         flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid)));
 
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h
index c4ac095..f5e9423 100644
--- a/runtime/vm/compiler/call_specializer.h
+++ b/runtime/vm/compiler/call_specializer.h
@@ -144,7 +144,7 @@
   const bool should_clone_fields_;
 
  private:
-  bool TypeCheckAsClassEquality(const AbstractType& type);
+  bool TypeCheckAsClassEquality(const AbstractType& type, intptr_t* type_cid);
 
   // Insert a Smi check if needed.
   void AddCheckSmi(Definition* to_check,
diff --git a/runtime/vm/compiler/cha.cc b/runtime/vm/compiler/cha.cc
index 06888b6..8d23e00 100644
--- a/runtime/vm/compiler/cha.cc
+++ b/runtime/vm/compiler/cha.cc
@@ -4,7 +4,9 @@
 
 #include "vm/compiler/cha.h"
 #include "vm/class_table.h"
+#include "vm/compiler/compiler_state.h"
 #include "vm/flags.h"
+#include "vm/log.h"
 #include "vm/object.h"
 #include "vm/raw_object.h"
 #include "vm/visitor.h"
@@ -12,15 +14,36 @@
 namespace dart {
 
 void CHA::AddToGuardedClasses(const Class& cls, intptr_t subclass_count) {
+  ASSERT(subclass_count >= 0);
   for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
     if (guarded_classes_[i].cls->ptr() == cls.ptr()) {
+      // Was added as an interface guard.
+      if (guarded_classes_[i].subclass_count == -1) {
+        guarded_classes_[i].subclass_count = subclass_count;
+      }
       return;
     }
   }
   GuardedClassInfo info = {&Class::ZoneHandle(thread_->zone(), cls.ptr()),
-                           subclass_count};
+                           subclass_count, kIllegalCid};
   guarded_classes_.Add(info);
-  return;
+}
+
+void CHA::AddToGuardedInterfaces(const Class& cls, intptr_t implementor_cid) {
+  ASSERT(implementor_cid != kIllegalCid);
+  ASSERT(implementor_cid != kDynamicCid);
+  for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
+    if (guarded_classes_[i].cls->ptr() == cls.ptr()) {
+      // Was added as a subclass guard.
+      if (guarded_classes_[i].implementor_cid == kIllegalCid) {
+        guarded_classes_[i].implementor_cid = implementor_cid;
+      }
+      return;
+    }
+  }
+  GuardedClassInfo info = {&Class::ZoneHandle(thread_->zone(), cls.ptr()), -1,
+                           implementor_cid};
+  guarded_classes_.Add(info);
 }
 
 bool CHA::IsGuardedClass(intptr_t cid) const {
@@ -93,6 +116,33 @@
   return cls.is_implemented();
 }
 
+bool CHA::HasSingleConcreteImplementation(const Class& interface,
+                                          intptr_t* implementation_cid) {
+  intptr_t cid = interface.implementor_cid();
+  if ((cid == kIllegalCid) || (cid == kDynamicCid)) {
+    // No implementations / multiple implementations.
+    *implementation_cid = kDynamicCid;
+    return false;
+  }
+
+  Thread* thread = Thread::Current();
+  if (FLAG_use_cha_deopt || thread->isolate_group()->all_classes_finalized()) {
+    if (FLAG_trace_cha) {
+      THR_Print("  **(CHA) Type has one implementation: %s\n",
+                interface.ToCString());
+    }
+    if (FLAG_use_cha_deopt) {
+      CHA& cha = thread->compiler_state().cha();
+      cha.AddToGuardedInterfaces(interface, cid);
+    }
+    *implementation_cid = cid;
+    return true;
+  } else {
+    *implementation_cid = kDynamicCid;
+    return false;
+  }
+}
+
 static intptr_t CountFinalizedSubclasses(Thread* thread, const Class& cls) {
   intptr_t count = 0;
   const GrowableObjectArray& cls_direct_subclasses =
@@ -114,10 +164,19 @@
 
 bool CHA::IsConsistentWithCurrentHierarchy() const {
   for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
-    const intptr_t subclass_count =
-        CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls);
-    if (guarded_classes_[i].subclass_count != subclass_count) {
-      return false;
+    if (guarded_classes_[i].subclass_count != -1) {
+      intptr_t current_subclass_count =
+          CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls);
+      if (guarded_classes_[i].subclass_count != current_subclass_count) {
+        return false;  // New subclass appeared during compilation.
+      }
+    }
+    if (guarded_classes_[i].implementor_cid != kIllegalCid) {
+      intptr_t current_implementor_cid =
+          guarded_classes_[i].cls->implementor_cid();
+      if (guarded_classes_[i].implementor_cid != current_implementor_cid) {
+        return false;  // New implementor appeared during compilation.
+      }
     }
   }
   return true;
diff --git a/runtime/vm/compiler/cha.h b/runtime/vm/compiler/cha.h
index dd1d5b3..a52bd3e 100644
--- a/runtime/vm/compiler/cha.h
+++ b/runtime/vm/compiler/cha.h
@@ -37,9 +37,15 @@
   static bool ConcreteSubclasses(const Class& cls,
                                  GrowableArray<intptr_t>* class_ids);
 
-  // Return true if the class is implemented by some other class.
+  // Return true if the class is implemented by some other class that is not a
+  // subclass.
   static bool IsImplemented(const Class& cls);
 
+  // Return true if there is only one concrete class that implements
+  // 'interface'.
+  static bool HasSingleConcreteImplementation(const Class& interface,
+                                              intptr_t* implementation_cid);
+
   // Returns true if any subclass of 'cls' contains the function.
   // If no override was found subclass_count would contain total count of
   // finalized subclasses that CHA looked at.
@@ -49,10 +55,12 @@
                    const String& function_name,
                    intptr_t* subclass_count);
 
-  // Adds class 'cls' to the list of guarded classes, deoptimization occurs
-  // if any of those classes gets subclassed through later loaded/finalized
-  // libraries. Only classes that were used for CHA optimizations are added.
+  // Adds class 'cls' to the list of guarded classes / interfaces.
+  // Deoptimization occurs if any of those classes gets subclassed or
+  // implemented through later loaded/finalized libraries. Only classes that
+  // were used for CHA optimizations are added.
   void AddToGuardedClasses(const Class& cls, intptr_t subclass_count);
+  void AddToGuardedInterfaces(const Class& cls, intptr_t implementor_cid);
 
   // When compiling in background we need to check that no new finalized
   // subclasses were added to guarded classes.
@@ -74,6 +82,12 @@
     // Used to validate correctness of background compilation: if
     // any subclasses were added we will discard compiled code.
     intptr_t subclass_count;
+
+    // Value of implementor_cid that this class had at the moment
+    // when CHA made the first decision based on this class.
+    // Used to validate correctness of background compilation: if
+    // any implementors were added we will discard compiled code.
+    intptr_t implementor_cid;
   };
 
   GrowableArray<GuardedClassInfo> guarded_classes_;
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 098de96..078b14d 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -119,10 +119,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     52;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    88;
+    92;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 100;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
@@ -583,7 +583,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 112;
+static constexpr dart::compiler::target::word Class_InstanceSize = 116;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@@ -780,10 +780,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     104;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
+    168;
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -1446,10 +1446,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     52;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    88;
+    92;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 100;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
@@ -1907,7 +1907,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 112;
+static constexpr dart::compiler::target::word Class_InstanceSize = 116;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@@ -2104,10 +2104,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     104;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
+    168;
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -2771,10 +2771,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    92;
+    96;
 static constexpr dart::compiler::target::word Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 104;
+    Class_host_type_arguments_field_offset_in_words_offset = 108;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 24;
@@ -3437,10 +3437,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    92;
+    96;
 static constexpr dart::compiler::target::word Class_super_type_offset = 48;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 104;
+    Class_host_type_arguments_field_offset_in_words_offset = 108;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 24;
@@ -4104,10 +4104,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     52;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    88;
+    92;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 100;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
@@ -4570,7 +4570,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 112;
+static constexpr dart::compiler::target::word Class_InstanceSize = 116;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@@ -4767,10 +4767,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     104;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    164;
+    168;
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 176;
+    Class_host_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
     SharedClassTable_class_heap_stats_table_offset = 0;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -5433,10 +5433,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     48;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    84;
+    88;
 static constexpr dart::compiler::target::word Class_super_type_offset = 40;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 96;
+    Class_host_type_arguments_field_offset_in_words_offset = 100;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -5892,7 +5892,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 108;
+static constexpr dart::compiler::target::word Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@@ -6086,10 +6086,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     96;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    156;
+    160;
 static constexpr dart::compiler::target::word Class_super_type_offset = 80;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 168;
+    Class_host_type_arguments_field_offset_in_words_offset = 172;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -6744,10 +6744,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     48;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    84;
+    88;
 static constexpr dart::compiler::target::word Class_super_type_offset = 40;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 96;
+    Class_host_type_arguments_field_offset_in_words_offset = 100;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -7200,7 +7200,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 108;
+static constexpr dart::compiler::target::word Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@@ -7394,10 +7394,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     96;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    156;
+    160;
 static constexpr dart::compiler::target::word Class_super_type_offset = 80;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 168;
+    Class_host_type_arguments_field_offset_in_words_offset = 172;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
@@ -8053,10 +8053,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     52;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    88;
+    92;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 100;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word Closure_context_offset = 24;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 16;
@@ -8519,7 +8519,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 16;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 112;
+static constexpr dart::compiler::target::word Class_InstanceSize = 120;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 32;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@@ -8711,10 +8711,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     52;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    88;
+    92;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 100;
+    Class_host_type_arguments_field_offset_in_words_offset = 104;
 static constexpr dart::compiler::target::word Closure_context_offset = 24;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 16;
@@ -9178,7 +9178,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 16;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 112;
+static constexpr dart::compiler::target::word Class_InstanceSize = 120;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 32;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 24;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
@@ -9370,10 +9370,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     48;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    84;
+    88;
 static constexpr dart::compiler::target::word Class_super_type_offset = 40;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 96;
+    Class_host_type_arguments_field_offset_in_words_offset = 100;
 static constexpr dart::compiler::target::word Closure_context_offset = 20;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 12;
@@ -9831,7 +9831,7 @@
 static constexpr dart::compiler::target::word Array_header_size = 12;
 static constexpr dart::compiler::target::word Bool_InstanceSize = 8;
 static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 108;
+static constexpr dart::compiler::target::word Class_InstanceSize = 112;
 static constexpr dart::compiler::target::word Closure_InstanceSize = 28;
 static constexpr dart::compiler::target::word ClosureData_InstanceSize = 20;
 static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 8;
@@ -10025,10 +10025,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     96;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    156;
+    160;
 static constexpr dart::compiler::target::word Class_super_type_offset = 80;
 static constexpr dart::compiler::target::word
-    Class_host_type_arguments_field_offset_in_words_offset = 168;
+    Class_host_type_arguments_field_offset_in_words_offset = 172;
 static constexpr dart::compiler::target::word Closure_context_offset = 40;
 static constexpr dart::compiler::target::word
     Closure_delayed_type_arguments_offset = 24;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index fa75c09..4af9fe1 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1395,6 +1395,13 @@
         }
       }
 #endif
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      if (obj->IsClass()) {
+        // Won't be able to update read-only VM isolate classes if implementors
+        // are discovered later.
+        static_cast<ClassPtr>(obj)->untag()->implementor_cid_ = kDynamicCid;
+      }
+#endif
     }
   }
 
@@ -2984,6 +2991,7 @@
                                target_next_field_offset);
   COMPILE_ASSERT((FakeObject::kClassId != kInstanceCid));
   result.set_id(FakeObject::kClassId);
+  NOT_IN_PRECOMPILED(result.set_implementor_cid(kIllegalCid));
   result.set_num_type_arguments_unsafe(0);
   result.set_num_native_fields(0);
   result.set_state_bits(0);
@@ -4741,6 +4749,7 @@
   result.set_next_field_offset(host_next_field_offset,
                                target_next_field_offset);
   result.set_id(index);
+  NOT_IN_PRECOMPILED(result.set_implementor_cid(kIllegalCid));
   result.set_num_type_arguments_unsafe(kUnknownNumTypeArguments);
   result.set_num_native_fields(0);
   result.set_state_bits(0);
@@ -4826,6 +4835,7 @@
     cls.set_is_declaration_loaded();
     cls.set_is_type_finalized();
     cls.set_is_synthesized_class();
+    NOT_IN_PRECOMPILED(cls.set_implementor_cid(kDynamicCid));
     library.AddClass(cls);
     return cls.ptr();
   } else {
@@ -5147,6 +5157,27 @@
   ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&untag()->end_token_pos_, token_pos);
 }
+
+void Class::set_implementor_cid(intptr_t value) const {
+  ASSERT(value >= 0 && value < std::numeric_limits<classid_t>::max());
+  StoreNonPointer(&untag()->implementor_cid_, value);
+}
+
+bool Class::NoteImplementor(const Class& implementor) const {
+  ASSERT(!implementor.is_abstract());
+  ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
+  if (implementor_cid() == kDynamicCid) {
+    return false;
+  } else if (implementor_cid() == implementor.id()) {
+    return false;
+  } else if (implementor_cid() == kIllegalCid) {
+    set_implementor_cid(implementor.id());
+    return true;  // None -> One
+  } else {
+    set_implementor_cid(kDynamicCid);
+    return true;  // One -> Many
+  }
+}
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 int32_t Class::SourceFingerprint() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3c6cc54..28feedf 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1110,6 +1110,19 @@
     StoreNonPointer(&untag()->id_, value);
   }
   static intptr_t id_offset() { return OFFSET_OF(UntaggedClass, id_); }
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // If the interface of this class has a single concrete implementation, either
+  // via `extends` or by `implements`, returns its CID.
+  // If it has no implementation, returns kIllegalCid.
+  // If it has more than one implementation, returns kDynamicCid.
+  intptr_t implementor_cid() const { return untag()->implementor_cid_; }
+
+  // Returns true if the implementor tracking state changes and so must be
+  // propagated to this class's superclass and interfaces.
+  bool NoteImplementor(const Class& implementor) const;
+#endif
+
   static intptr_t num_type_arguments_offset() {
     return OFFSET_OF(UntaggedClass, num_type_arguments_);
   }
@@ -1531,6 +1544,9 @@
     return RoundedAllocationSize(sizeof(UntaggedClass));
   }
 
+  // Returns true if any class implements this interface via `implements`.
+  // Returns false if all possible implementations of this interface must be
+  // instances of this class or its subclasses.
   bool is_implemented() const { return ImplementedBit::decode(state_bits()); }
   void set_is_implemented() const;
   void set_is_implemented_unsafe() const;
@@ -1874,6 +1890,7 @@
   void set_user_name(const String& value) const;
   const char* GenerateUserVisibleName() const;
   void set_state_bits(intptr_t bits) const;
+  void set_implementor_cid(intptr_t value) const;
 
   FunctionPtr CreateInvocationDispatcher(const String& target_name,
                                          const Array& args_desc,
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 2df9119..3cc7a2b 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -5358,6 +5358,91 @@
   EXPECT(class_a_sub.implements_finalizable());
 }
 
+TEST_CASE(ImplementorCid) {
+  const char* kScriptChars = R"(
+abstract class AInterface {}
+
+abstract class BInterface {}
+class BImplementation implements BInterface {}
+
+abstract class CInterface {}
+class CImplementation1 implements CInterface {}
+class CImplementation2 implements CInterface {}
+
+abstract class DInterface {}
+abstract class DSubinterface implements DInterface {}
+
+abstract class EInterface {}
+abstract class ESubinterface implements EInterface {}
+class EImplementation implements ESubinterface {}
+
+abstract class FInterface {}
+abstract class FSubinterface implements FInterface {}
+class FImplementation1 implements FSubinterface {}
+class FImplementation2 implements FSubinterface {}
+
+main() {
+  new BImplementation();
+  new CImplementation1();
+  new CImplementation2();
+  new EImplementation();
+  new FImplementation1();
+  new FImplementation2();
+}
+)";
+  Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  EXPECT_VALID(h_lib);
+  Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+  TransitionNativeToVM transition(thread);
+  const Library& lib =
+      Library::CheckedHandle(thread->zone(), Api::UnwrapHandle(h_lib));
+  EXPECT(!lib.IsNull());
+
+  const Class& AInterface = Class::Handle(GetClass(lib, "AInterface"));
+  EXPECT_EQ(AInterface.implementor_cid(), kIllegalCid);
+
+  const Class& BInterface = Class::Handle(GetClass(lib, "BInterface"));
+  const Class& BImplementation =
+      Class::Handle(GetClass(lib, "BImplementation"));
+  EXPECT_EQ(BInterface.implementor_cid(), BImplementation.id());
+  EXPECT_EQ(BImplementation.implementor_cid(), BImplementation.id());
+
+  const Class& CInterface = Class::Handle(GetClass(lib, "CInterface"));
+  const Class& CImplementation1 =
+      Class::Handle(GetClass(lib, "CImplementation1"));
+  const Class& CImplementation2 =
+      Class::Handle(GetClass(lib, "CImplementation2"));
+  EXPECT_EQ(CInterface.implementor_cid(), kDynamicCid);
+  EXPECT_EQ(CImplementation1.implementor_cid(), CImplementation1.id());
+  EXPECT_EQ(CImplementation2.implementor_cid(), CImplementation2.id());
+
+  const Class& DInterface = Class::Handle(GetClass(lib, "DInterface"));
+  const Class& DSubinterface = Class::Handle(GetClass(lib, "DSubinterface"));
+  EXPECT_EQ(DInterface.implementor_cid(), kIllegalCid);
+  EXPECT_EQ(DSubinterface.implementor_cid(), kIllegalCid);
+
+  const Class& EInterface = Class::Handle(GetClass(lib, "EInterface"));
+  const Class& ESubinterface = Class::Handle(GetClass(lib, "ESubinterface"));
+  const Class& EImplementation =
+      Class::Handle(GetClass(lib, "EImplementation"));
+  EXPECT_EQ(EInterface.implementor_cid(), EImplementation.id());
+  EXPECT_EQ(ESubinterface.implementor_cid(), EImplementation.id());
+  EXPECT_EQ(EImplementation.implementor_cid(), EImplementation.id());
+
+  const Class& FInterface = Class::Handle(GetClass(lib, "FInterface"));
+  const Class& FSubinterface = Class::Handle(GetClass(lib, "FSubinterface"));
+  const Class& FImplementation1 =
+      Class::Handle(GetClass(lib, "FImplementation1"));
+  const Class& FImplementation2 =
+      Class::Handle(GetClass(lib, "FImplementation2"));
+  EXPECT_EQ(FInterface.implementor_cid(), kDynamicCid);
+  EXPECT_EQ(FSubinterface.implementor_cid(), kDynamicCid);
+  EXPECT_EQ(FImplementation1.implementor_cid(), FImplementation1.id());
+  EXPECT_EQ(FImplementation2.implementor_cid(), FImplementation2.id());
+}
+
 ISOLATE_UNIT_TEST_CASE(MirrorReference) {
   const MirrorReference& reference =
       MirrorReference::Handle(MirrorReference::New(Object::Handle()));
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index b4fb7b6..7acfa30 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1059,6 +1059,7 @@
 
   NOT_IN_PRECOMPILED(TokenPosition token_pos_);
   NOT_IN_PRECOMPILED(TokenPosition end_token_pos_);
+  NOT_IN_PRECOMPILED(classid_t implementor_cid_);
 
   classid_t id_;                // Class Id, also index in the class table.
   int16_t num_type_arguments_;  // Number of type arguments in flattened vector.
@@ -1099,6 +1100,7 @@
   friend class InstanceSerializationCluster;
   friend class TypeSerializationCluster;
   friend class CidRewriteVisitor;
+  friend class FinalizeVMIsolateVisitor;
   friend class Api;
 };
 
diff --git a/sdk/lib/_internal/wasm/lib/symbol_patch.dart b/sdk/lib/_internal/wasm/lib/symbol_patch.dart
new file mode 100644
index 0000000..883847d
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/symbol_patch.dart
@@ -0,0 +1,68 @@
+// 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.
+
+// part of "internal_patch.dart";
+
+// TODO(49531): This file is nearly identical to the VM's
+// symbol_patch.dart, with the exception of the added pragma on `const Symbol`.
+// Unfortunately, adding this pragma to the VM's symbol_patch causes a
+// deadlock. When this bug is fixed we can share a patch file with the VM.
+
+@patch
+class Symbol {
+  // TODO(http://dartbug.com/46716): Recognize Symbol in the VM.
+  @patch
+  @pragma("wasm:entry-point")
+  const Symbol(String name) : this._name = name;
+
+  @patch
+  String toString() => 'Symbol("${computeUnmangledName(this)}")';
+
+  @patch
+  static String computeUnmangledName(Symbol symbol) {
+    String string = Symbol.getName(symbol);
+
+    // get:foo -> foo
+    // set:foo -> foo=
+    // get:_foo@xxx -> _foo
+    // set:_foo@xxx -> _foo=
+    // Class._constructor@xxx -> Class._constructor
+    // _Class@xxx._constructor@xxx -> _Class._constructor
+    // lib._S@xxx with lib._M1@xxx, lib._M2@xxx -> lib._S with lib._M1, lib._M2
+    StringBuffer result = new StringBuffer();
+    bool add_setter_suffix = false;
+    var pos = 0;
+    if (string.length >= 4 && string[3] == ':') {
+      // Drop 'get:' or 'set:' prefix.
+      pos = 4;
+      if (string[0] == 's') {
+        add_setter_suffix = true;
+      }
+    }
+    // Skip everything between AT and PERIOD, SPACE, COMMA or END
+    bool skip = false;
+    for (; pos < string.length; pos++) {
+      var char = string[pos];
+      if (char == '@') {
+        skip = true;
+      } else if (char == '.' || char == ' ' || char == ',') {
+        skip = false;
+      }
+      if (!skip) {
+        result.write(char);
+      }
+    }
+    if (add_setter_suffix) {
+      result.write('=');
+    }
+    return result.toString();
+  }
+
+  // Must be kept in sync with Symbol::CanonicalizeHash in object.cc.
+  @patch
+  int get hashCode {
+    const arbitraryPrime = 664597;
+    return 0x1fffffff & (arbitraryPrime * _name.hashCode);
+  }
+}
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 9f93f8b..5107be5 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -168,7 +168,7 @@
           "_internal/wasm/lib/class_id.dart",
           "_internal/wasm/lib/patch.dart",
           "_internal/wasm/lib/print_patch.dart",
-          "_internal/vm/lib/symbol_patch.dart"
+          "_internal/wasm/lib/symbol_patch.dart"
         ]
       },
       "_js_helper": {
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index b1a0e70..f9f859e 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -165,7 +165,7 @@
       - _internal/wasm/lib/class_id.dart
       - _internal/wasm/lib/patch.dart
       - _internal/wasm/lib/print_patch.dart
-      - _internal/vm/lib/symbol_patch.dart
+      - _internal/wasm/lib/symbol_patch.dart
     _js_helper:
       uri: _internal/wasm/lib/js_helper.dart
     async:
diff --git a/tools/VERSION b/tools/VERSION
index 2637c99..6112c90 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 19
 PATCH 0
-PRERELEASE 36
+PRERELEASE 37
 PRERELEASE_PATCH 0
\ No newline at end of file