Version 2.6.0-dev.5.0

Merge commit '5c106e3098bb64139e6c91cd5a57b82bbe662111' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec7b523..81f49ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,16 +31,20 @@
 
 #### Linter
 
-The Linter was updated to `0.1.98`, which includes:
+The Linter was updated to `0.1.99`, which includes:
 
-* fixed null raw expression accesses in `use_to_and_as_if_applicable`
-* internal migration to using analyzer `InheritanceManager3`
-* internal migration away from using analyzer `resolutionMap`
-* various fixes and improvements to anticipate support for extension-methods
-* new lint: `camel_case_extensions`
-* rule template generation improvements
-* new lint: `avoid_equals_and_hash_code_on_mutable_classes`
-* extended `avoid_slow_async_io` to flag async `Directory` methods
+* fixed unsafe casts in `overridden_fields`
+* (internal) migration to the mock SDK in `package:analyzer` for testing
+* fixed empty argument list access in `use_full_hex_values_for_flutter_color_fix`
+* new lint: `prefer_relative_imports`
+* improved messages for `await_only_futures`
+
+## 2.5.1 - 2019-09-27
+
+This is a patch release that prevents type inference failures in the analyzer
+(Issue [38365][]).
+
+[38365]: https://github.com/dart-lang/sdk/issues/38365
 
 ## 2.5.0 - 2019-09-10
 
diff --git a/DEPS b/DEPS
index 60b6900..3090e38 100644
--- a/DEPS
+++ b/DEPS
@@ -99,7 +99,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.98",
+  "linter_tag": "0.1.99",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.1.1",
@@ -136,7 +136,7 @@
   "test_descriptor_tag": "1.1.1",
   "test_process_tag": "1.0.3",
   "term_glyph_tag": "1.0.1",
-  "test_reflective_loader_tag": "0.1.8",
+  "test_reflective_loader_tag": "0.1.9",
   "test_tag": "test-v1.6.4",
   "tflite_native_rev": "06e533a9747306d1114c53427cc67eda080f51f9",
   "typed_data_tag": "1.1.6",
@@ -174,7 +174,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.6.0-dev.3.0",
+          "version": "version:2.6.0-dev.4.0",
       }],
       "dep_type": "cipd",
   },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index abfe139..b7a443f 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -216,18 +216,25 @@
         return []
 
     local_root = input_api.change.RepositoryRoot()
-    layering_check = imp.load_source(
-        'layering_check',
-        os.path.join(local_root, 'runtime', 'tools', 'layering_check.py'))
-    errors = layering_check.DoCheck(local_root)
+    compiler_layering_check = imp.load_source(
+        'compiler_layering_check',
+        os.path.join(local_root, 'runtime', 'tools',
+                     'compiler_layering_check.py'))
+    errors = compiler_layering_check.DoCheck(local_root)
+    embedder_layering_check = imp.load_source(
+        'embedder_layering_check',
+        os.path.join(local_root, 'runtime', 'tools',
+                     'embedder_layering_check.py'))
+    errors += embedder_layering_check.DoCheck(local_root)
     if errors:
         return [
             output_api.PresubmitError(
                 'Layering check violation for C++ sources.',
                 long_text='\n'.join(errors))
         ]
-    else:
-        return []
+
+    return []
+
 
 def _CheckClangTidy(input_api, output_api):
     """Run clang-tidy on VM changes."""
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 109e3fc..e5254c7 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -130,6 +130,10 @@
 
   # Compile for Thread Sanitizer to find threading bugs.
   is_tsan = false
+
+  # Whether to use the NNBD fork of the SDK core libraries.
+  # TODO(rnystrom): Remove this when the fork has been merged back in.
+  use_nnbd = false
 }
 
 # =============================================================================
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index ef4751b..0b33895 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -6,12 +6,13 @@
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_css.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_js.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/highlight_js.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/highlight_css.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -216,30 +217,46 @@
 
   /// Generate output into the given [folder].
   void _generateOutput(OverlayResourceProvider provider, Folder folder) async {
-    List<LibraryInfo> libraryInfos =
-        await InfoBuilder(instrumentationListener.data, listener)
-            .explainMigration();
+    // Remove any previously generated output.
+    folder.getChildren().forEach((resource) => resource.delete());
+    // Gather the data needed in order to produce the output.
+    InfoBuilder infoBuilder =
+        InfoBuilder(instrumentationListener.data, listener);
+    List<UnitInfo> unitInfos = await infoBuilder.explainMigration();
     var pathContext = provider.pathContext;
     MigrationInfo migrationInfo =
-        MigrationInfo(libraryInfos, pathContext, includedRoot);
-    for (LibraryInfo info in libraryInfos) {
-      assert(info.units.isNotEmpty);
-      String libraryPath =
-          pathContext.setExtension(info.units.first.path, '.html');
-      String relativePath =
-          pathContext.relative(libraryPath, from: includedRoot);
-      List<String> directories =
-          pathContext.split(pathContext.dirname(relativePath));
-      for (int i = 0; i < directories.length; i++) {
-        String directory = pathContext.joinAll(directories.sublist(0, i + 1));
-        folder.getChildAssumingFolder(directory).create();
-      }
-      File output =
-          provider.getFile(pathContext.join(folder.path, relativePath));
-      String rendered = InstrumentationRenderer(info, migrationInfo).render();
+        MigrationInfo(unitInfos, pathContext, includedRoot);
+    PathMapper pathMapper = PathMapper(provider, folder.path, includedRoot);
+
+    /// Produce output for the compilation unit represented by the [unitInfo].
+    void render(UnitInfo unitInfo) {
+      File output = provider.getFile(pathMapper.map(unitInfo.path));
+      output.parent.create();
+      String rendered =
+          InstrumentationRenderer(unitInfo, migrationInfo, pathMapper).render();
       output.writeAsStringSync(rendered);
     }
-    // Generate resource files:
+
+    // Generate the files in the package being migrated.
+    for (UnitInfo unitInfo in unitInfos) {
+      render(unitInfo);
+    }
+    // Generate other dart files.
+    for (UnitInfo unitInfo in infoBuilder.unitMap.values) {
+      if (!unitInfos.contains(unitInfo)) {
+        if (unitInfo.content == null) {
+          try {
+            unitInfo.content =
+                provider.getFile(unitInfo.path).readAsStringSync();
+          } catch (_) {
+            // If we can't read the content of the file, then skip it.
+            continue;
+          }
+        }
+        render(unitInfo);
+      }
+    }
+    // Generate resource files.
     File highlightJsOutput =
         provider.getFile(pathContext.join(folder.path, 'highlight.pack.js'));
     highlightJsOutput.writeAsStringSync(decodeHighlightJs());
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
index 694a210..950e06f 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
@@ -10,9 +11,12 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show Location, SourceEdit, SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
+import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 
@@ -48,20 +52,60 @@
 
   /// Return the migration information for all of the libraries that were
   /// migrated.
-  Future<List<LibraryInfo>> explainMigration() async {
-    Map<Source, SourceInformation> sourceInfo = info.sourceInformation;
-    List<LibraryInfo> libraries = [];
-    for (Source source in sourceInfo.keys) {
+  Future<List<UnitInfo>> explainMigration() async {
+    Map<Source, SourceInformation> sourceInfoMap = info.sourceInformation;
+    List<UnitInfo> units = [];
+    for (Source source in sourceInfoMap.keys) {
       String filePath = source.fullName;
       AnalysisSession session =
           server.getAnalysisDriver(filePath).currentSession;
       if (!session.getFile(filePath).isPart) {
-        ParsedLibraryResult result = await session.getParsedLibrary(filePath);
-        libraries
-            .add(_explainLibrary(result, info, sourceInfo[source], listener));
+        ResolvedLibraryResult result =
+            await session.getResolvedLibrary(filePath);
+        SourceInformation sourceInfo = sourceInfoMap[source];
+        for (ResolvedUnitResult unitResult in result.units) {
+          SourceFileEdit edit =
+              listener.sourceChange.getFileEdit(unitResult.path);
+          units.add(_explainUnit(sourceInfo, unitResult, edit));
+        }
       }
     }
-    return libraries;
+    return units;
+  }
+
+  /// Return details for a fix built from the given [edge], or `null` if the
+  /// edge does not have an origin.
+  String _buildDescriptionForDestination(AstNode node) {
+    // Other found types:
+    // - ConstructorDeclaration
+    if (node.parent is FormalParameterList) {
+      return "A nullable value can't be passed as an argument";
+    } else {
+      return "A nullable value can't be used here";
+    }
+  }
+
+  /// Return details for a fix built from the given [edge], or `null` if the
+  /// edge does not have an origin.
+  String _buildDescriptionForOrigin(AstNode node) {
+    String /*!*/ description;
+    if (node.parent is ArgumentList) {
+      if (node is NullLiteral) {
+        description = "An explicit 'null' is passed as an argument";
+      } else {
+        description = "A nullable value is explicitly passed as an argument";
+      }
+    } else {
+      if (node is NullLiteral) {
+        description = "An explicit 'null' is assigned";
+      } else {
+        description = "A nullable value is assigned";
+      }
+    }
+    if (_inTestCode(node)) {
+      description += " in test code";
+    }
+    return description;
   }
 
   /// Compute the details for the fix with the given [fixInfo].
@@ -70,28 +114,26 @@
     for (FixReasonInfo reason in fixInfo.reasons) {
       if (reason is NullabilityNodeInfo) {
         for (EdgeInfo edge in reason.upstreamEdges) {
-          EdgeOriginInfo origin = info.edgeOrigin[edge];
-          if (origin != null) {
-            AstNode node = origin.node;
-            if (node.parent is ArgumentList) {
-              if (node is NullLiteral) {
-                details.add(RegionDetail(
-                    'null is explicitly passed as an argument.',
-                    _targetFor(origin)));
-              } else {
-                details.add(RegionDetail(
-                    'A nullable value is explicitly passed as an argument.',
-                    _targetFor(origin)));
-              }
-            } else {
-              details.add(RegionDetail(
-                  'A nullable value is assigned.', _targetFor(origin)));
+          if (edge.isTriggered) {
+            EdgeOriginInfo origin = info.edgeOrigin[edge];
+            if (origin != null) {
+              // TODO(brianwilkerson) If the origin is an InheritanceOrigin then
+              //  the node is the method declaration in the subclass and we want
+              //  to link to the corresponding parameter in the declaration in
+              //  the superclass.
+              details.add(RegionDetail(_buildDescriptionForOrigin(origin.node),
+                  _targetForNode(origin.source.fullName, origin.node)));
             }
           }
         }
       } else if (reason is EdgeInfo) {
-        // TODO(brianwilkerson) Implement this after finding an example whose
-        //  reason is an edge.
+        NullabilityNodeInfo destination = reason.destinationNode;
+        var nodeInfo = info.nodeInfoFor(destination);
+        if (nodeInfo != null) {
+          details.add(RegionDetail(
+              _buildDescriptionForDestination(nodeInfo.astNode),
+              _targetForNode(nodeInfo.filePath, nodeInfo.astNode)));
+        }
       } else {
         throw UnimplementedError(
             'Unexpected class of reason: ${reason.runtimeType}');
@@ -100,24 +142,41 @@
     return details;
   }
 
-  /// Return the migration information for the given library.
-  LibraryInfo _explainLibrary(
-      ParsedLibraryResult result,
-      InstrumentationInformation info,
-      SourceInformation sourceInfo,
-      DartFixListener listener) {
-    List<UnitInfo> units = [];
-    for (ParsedUnitResult unit in result.units) {
-      SourceFileEdit edit = listener.sourceChange.getFileEdit(unit.path);
-      units.add(_explainUnit(sourceInfo, unit, edit));
-    }
-    return LibraryInfo(units);
+  /// Return the navigation sources for the unit associated with the [result].
+  List<NavigationSource> _computeNavigationSources(ResolvedUnitResult result) {
+    NavigationCollectorImpl collector = new NavigationCollectorImpl();
+    computeDartNavigation(
+        result.session.resourceProvider, collector, result.unit, null, null);
+    collector.createRegions();
+    List<String> files = collector.files;
+    List<protocol.NavigationRegion> regions = collector.regions;
+    List<protocol.NavigationTarget> rawTargets = collector.targets;
+    List<NavigationTarget> convertedTargets =
+        List<NavigationTarget>(rawTargets.length);
+    return regions.map((region) {
+      List<int> targets = region.targets;
+      if (targets.isEmpty) {
+        throw StateError('Targets is empty');
+      }
+      NavigationTarget target = convertedTargets[targets[0]];
+      if (target == null) {
+        protocol.NavigationTarget rawTarget = rawTargets[targets[0]];
+        target = _targetFor(
+            files[rawTarget.fileIndex], rawTarget.offset, rawTarget.length);
+        convertedTargets[targets[0]] = target;
+      }
+      return NavigationSource(region.offset, region.length, target);
+    }).toList();
   }
 
-  /// Return the migration information for the given unit.
-  UnitInfo _explainUnit(SourceInformation sourceInfo, ParsedUnitResult result,
+  /// Return the migration information for the unit associated with the
+  /// [result].
+  UnitInfo _explainUnit(SourceInformation sourceInfo, ResolvedUnitResult result,
       SourceFileEdit fileEdit) {
     UnitInfo unitInfo = _unitForPath(result.path);
+    if (unitInfo.sources == null) {
+      unitInfo.sources = _computeNavigationSources(result);
+    }
     String content = result.content;
     // [fileEdit] is null when a file has no edits.
     if (fileEdit != null) {
@@ -166,17 +225,35 @@
     return null;
   }
 
-  /// Return the navigation target corresponding to the given [origin].
-  NavigationTarget _targetFor(EdgeOriginInfo origin) {
-    AstNode node = origin.node;
-    String filePath = origin.source.fullName;
+  /// Return `true` if the given [node] is from a compilation unit within the
+  /// 'test' directory of the package.
+  bool _inTestCode(AstNode node) {
+    // TODO(brianwilkerson) Generalize this.
+    CompilationUnit unit = node.thisOrAncestorOfType<CompilationUnit>();
+    CompilationUnitElement unitElement = unit?.declaredElement;
+    if (unitElement == null) {
+      return false;
+    }
+    String filePath = unitElement.source.fullName;
+    var resourceProvider = unitElement.session.resourceProvider;
+    return resourceProvider.pathContext.split(filePath).contains('test');
+  }
+
+  /// Return the navigation target in the file with the given [filePath] at the
+  /// given [offset] ans with the given [length].
+  NavigationTarget _targetFor(String filePath, int offset, int length) {
     UnitInfo unitInfo = _unitForPath(filePath);
-    NavigationTarget target =
-        NavigationTarget(filePath, node.offset, node.length);
+    NavigationTarget target = NavigationTarget(filePath, offset, length);
     unitInfo.targets.add(target);
     return target;
   }
 
+  /// Return the navigation target corresponding to the given [node] in the file
+  /// with the given [filePath].
+  NavigationTarget _targetForNode(String filePath, AstNode node) {
+    return _targetFor(filePath, node.offset, node.length);
+  }
+
   /// Return the unit info for the file at the given [path].
   UnitInfo _unitForPath(String path) {
     return unitMap.putIfAbsent(path, () => UnitInfo(path));
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
index 1e60891..e1b1938 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
@@ -34,6 +34,55 @@
 
   /// Initialize a newly created holder of instrumentation information.
   InstrumentationInformation();
+
+  /// Return information about the given [node].
+  NodeInformation nodeInfoFor(NullabilityNodeInfo node) {
+    for (MapEntry<Source, SourceInformation> sourceEntry
+        in sourceInformation.entries) {
+      SourceInformation sourceInfo = sourceEntry.value;
+      for (MapEntry<AstNode, DecoratedTypeInfo> entry
+          in sourceInfo.implicitReturnType.entries) {
+        if (entry.value.node == node) {
+          return NodeInformation(
+              sourceEntry.key.fullName, entry.key, entry.value);
+        }
+      }
+      for (MapEntry<AstNode, DecoratedTypeInfo> entry
+          in sourceInfo.implicitType.entries) {
+        if (entry.value.node == node) {
+          return NodeInformation(
+              sourceEntry.key.fullName, entry.key, entry.value);
+        }
+      }
+      for (MapEntry<AstNode, List<DecoratedTypeInfo>> entry
+          in sourceInfo.implicitTypeArguments.entries) {
+        for (var type in entry.value) {
+          if (type.node == node) {
+            return NodeInformation(sourceEntry.key.fullName, entry.key, type);
+          }
+        }
+      }
+    }
+    // The loop below doesn't help because we still don't have access to an AST
+    // node.
+//    for (MapEntry<Element, DecoratedTypeInfo> entry in externalDecoratedType.entries) {
+//      if (entry.value.node == node) {
+//        return NodeInformation(null, null, entry.value);
+//      }
+//    }
+    return null;
+  }
+}
+
+/// The instrumentation information about a [NullabilityNodeInfo].
+class NodeInformation {
+  final String filePath;
+
+  final AstNode astNode;
+
+  final DecoratedTypeInfo decoratedType;
+
+  NodeInformation(this.filePath, this.astNode, this.decoratedType);
 }
 
 /// The instrumentation information gathered from the migration engine that is
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
index 6735746..7e3812a 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
@@ -1,137 +1,45 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:meta/meta.dart';
 import 'package:mustache/mustache.dart' as mustache;
 import 'package:path/path.dart' as path;
 
-/// Instrumentation display output for a library that was migrated to use
-/// non-nullable types.
-class InstrumentationRenderer {
-  /// Display information for a library.
-  final LibraryInfo libraryInfo;
-
-  /// Information for a whole migration, so that libraries can reference each
-  /// other.
-  final MigrationInfo migrationInfo;
-
-  /// Creates an output object for the given library info.
-  InstrumentationRenderer(this.libraryInfo, this.migrationInfo);
-
-  /// Builds an HTML view of the instrumentation information in [libraryInfo].
-  String render() {
-    int previousIndex = 0;
-    Map<String, dynamic> mustacheContext = {
-      'units': <Map<String, dynamic>>[],
-      'links': migrationInfo.libraryLinks(libraryInfo),
-      'highlightJsPath': migrationInfo.highlightJsPath(libraryInfo),
-      'highlightStylePath': migrationInfo.highlightStylePath(libraryInfo),
-    };
-    for (var compilationUnit in libraryInfo.units) {
-      // List of Mustache context for both unmodified and modified regions:
-      //
-      // * 'modified': Whether this region represents modified source, or
-      //   unmodified.
-      // * 'content': The textual content of this region.
-      // * 'explanation': The textual explanation of why the content in this
-      //   region was modified. It will appear in a "tooltip" on hover.
-      //   TODO(srawlins): Support some sort of HTML explanation, with
-      //   hyperlinks to anchors in other source code.
-      List<Map> regions = [];
-      for (var region in compilationUnit.regions) {
-        if (region.offset > previousIndex) {
-          // Display a region of unmodified content.
-          regions.add({
-            'modified': false,
-            'content':
-                compilationUnit.content.substring(previousIndex, region.offset)
-          });
-          previousIndex = region.offset + region.length;
-        }
-        regions.add({
-          'modified': true,
-          'content': compilationUnit.content
-              .substring(region.offset, region.offset + region.length),
-          'explanation': region.explanation,
-        });
-      }
-      if (previousIndex < compilationUnit.content.length) {
-        // Last region of unmodified content.
-        regions.add({
-          'modified': false,
-          'content': compilationUnit.content.substring(previousIndex)
-        });
-      }
-      mustacheContext['units']
-          .add({'path': compilationUnit.path, 'regions': regions});
-    }
-    return _template.renderString(mustacheContext);
-  }
-}
-
-/// A class storing rendering information for an entire migration report.
-///
-/// This generally provides one [InstrumentationRenderer] (for one library)
-/// with information about the rest of the libraries represented in the
-/// instrumentation output.
-class MigrationInfo {
-  /// The information about the libraries that are are migrated.
-  final List<LibraryInfo> libraries;
-
-  /// The resource provider's path context.
-  final path.Context pathContext;
-
-  /// The filesystem root used to create relative paths for each unit.
-  final String includedRoot;
-
-  MigrationInfo(this.libraries, this.pathContext, this.includedRoot);
-
-  /// Generate mustache context for library links, for navigation in the
-  /// instrumentation document for [thisLibrary].
-  List<Map<String, Object>> libraryLinks(LibraryInfo thisLibrary) {
-    return [
-      for (var library in libraries)
-        {
-          'name': _computeName(library),
-          'isLink': library != thisLibrary,
-          if (library != thisLibrary)
-            'href': _pathTo(library, source: thisLibrary)
-        }
-    ];
-  }
-
-  /// Return the path to [library] from [includedRoot], to be used as a display
-  /// name for a library.
-  String _computeName(LibraryInfo library) =>
-      pathContext.relative(library.units.first.path, from: includedRoot);
-
-  /// The path to [target], relative to [from].
-  String _pathTo(LibraryInfo target, {@required LibraryInfo source}) {
-    assert(target.units.isNotEmpty);
-    assert(source.units.isNotEmpty);
-    String targetPath =
-        pathContext.setExtension(target.units.first.path, '.html');
-    String sourceDir = pathContext.dirname(source.units.first.path);
-    return pathContext.relative(targetPath, from: sourceDir);
-  }
-
-  /// The path to the highlight.js script, relative to [libraryInfo].
-  String highlightJsPath(LibraryInfo libraryInfo) =>
-      pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
-          from: pathContext.dirname(libraryInfo.units.first.path));
-
-  /// The path to the highlight.js stylesheet, relative to [libraryInfo].
-  String highlightStylePath(LibraryInfo libraryInfo) =>
-      pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
-          from: pathContext.dirname(libraryInfo.units.first.path));
-}
-
 /// A mustache template for one library's instrumentation output.
 mustache.Template _template = mustache.Template(r'''
 <html>
   <head>
     <title>Non-nullable fix instrumentation report</title>
-    <script src="{{ highlightJsPath }}"></script>
+<!--    <script src="{{ highlightJsPath }}"></script>-->
+    <script>
+    function highlightTarget() {
+      var url = document.URL;
+      var index = url.lastIndexOf("#");
+      if (index >= 0) {
+        var name = url.substring(index + 1);
+        var anchor = document.getElementById(name);
+        if (anchor != null) {
+          anchor.className = "target";
+        }
+      }
+    }
+    </script>
     <link rel="stylesheet" href="{{ highlightStylePath }}">
     <style>
+a:link {
+  color: #000000;
+  text-decoration-line: none;
+}
+
+a:visited {
+  color: #000000;
+  text-decoration-line: none;
+}
+
 body {
   font-family: sans-serif;
   padding: 1em;
@@ -142,6 +50,12 @@
   font-weight: bold;
 }
 
+.code {
+  position: absolute;
+  left: 0.5em;
+  top: 0.5em;
+}
+
 .content {
   font-family: monospace;
   position: relative;
@@ -181,16 +95,22 @@
   top: 100%;
   visibility: hidden;
   white-space: normal;
-  width: 200px;
+  width: 400px;
   z-index: 1;
 }
 
 .region:hover .tooltip {
   visibility: visible;
 }
+
+.target {
+  background-color: #FFFFFF;
+  position: relative;
+  visibility: visible;
+}
     </style>
   </head>
-  <body>
+  <body onload="highlightTarget()">
     <h1>Non-nullable fix instrumentation report</h1>
     <p><em>Well-written introduction to this report.</em></p>
     <div class="navigation">
@@ -203,20 +123,30 @@
     {{# units }}'''
     '<h2>{{{ path }}}</h2>'
     '<div class="content">'
-    '<div class="highlighting">'
-    '{{! These regions are written out, unmodified, as they need to be found }}'
-    '{{! in one simple text string for highlight.js to hightlight them. }}'
-    '{{# regions }}'
-    '{{ content }}'
-    '{{/ regions }}'
+//    '<div class="highlighting">'
+//    '{{! These regions are written out, unmodified, as they need to be found }}'
+//    '{{! in one simple text string for highlight.js to hightlight them. }}'
+//    '{{# regions }}'
+//    '{{ content }}'
+//    '{{/ regions }}'
+//    '</div>'
+    '<div class ="code">'
+    '{{! Write the file content, modified to include navigation information, }}'
+    '{{! both anchors and links. }}'
+    '{{{ navContent }}}'
     '</div>'
     '<div class="regions">'
-    '{{! The regions are then printed again, overlaying the first copy of the }}'
-    '{{! content, to provide tooltips for modified regions. }}'
+    '{{! The regions are then written again, overlaying the first two copies }}'
+    '{{! of the content, to provide tooltips for modified regions. }}'
     '{{# regions }}'
     '{{^ modified }}{{ content }}{{/ modified }}'
     '{{# modified }}<span class="region">{{ content }}'
-    '<span class="tooltip">{{explanation}}</span></span>{{/ modified }}'
+    '<span class="tooltip">{{ explanation }}<ul>'
+    '{{# details }}'
+    '<li>'
+    '<a href="{{ target }}">{{ description }}</a>'
+    '</li>'
+    '{{/ details }}</ul></span></span>{{/ modified }}'
     '{{/ regions }}'
     '</div></div>'
     r'''
@@ -230,3 +160,217 @@
     </script>
   </body>
 </html>''');
+
+/// Instrumentation display output for a library that was migrated to use
+/// non-nullable types.
+class InstrumentationRenderer {
+  /// Display information for a compilation unit.
+  final UnitInfo unitInfo;
+
+  /// Information for a whole migration, so that libraries can reference each
+  /// other.
+  final MigrationInfo migrationInfo;
+
+  /// An object used to map the file paths of analyzed files to the file paths
+  /// of the HTML files used to view the content of those files.
+  final PathMapper pathMapper;
+
+  /// Creates an output object for the given library info.
+  InstrumentationRenderer(this.unitInfo, this.migrationInfo, this.pathMapper);
+
+  /// Builds an HTML view of the instrumentation information in [unitInfo].
+  String render() {
+    Map<String, dynamic> mustacheContext = {
+      'units': <Map<String, dynamic>>[],
+      'links': migrationInfo.unitLinks(unitInfo),
+      'highlightJsPath': migrationInfo.highlightJsPath(unitInfo),
+      'highlightStylePath': migrationInfo.highlightStylePath(unitInfo),
+      'navContent': _computeNavigationContent(unitInfo),
+    };
+    mustacheContext['units'].add({
+      'path': unitInfo.path,
+      'regions': _computeRegions(unitInfo),
+    });
+    return _template.renderString(mustacheContext);
+  }
+
+  /// Return the content of the file with navigation links and anchors added.
+  String _computeNavigationContent(UnitInfo unitInfo) {
+    String content = unitInfo.content;
+    OffsetMapper mapper = unitInfo.offsetMapper;
+    List<NavigationRegion> regions = []
+      ..addAll(unitInfo.sources ?? <NavigationSource>[])
+      ..addAll(unitInfo.targets);
+    regions.sort((first, second) {
+      int offsetComparison = first.offset.compareTo(second.offset);
+      if (offsetComparison == 0) {
+        return first is NavigationSource ? -1 : 1;
+      }
+      return offsetComparison;
+    });
+
+    StringBuffer navContent = StringBuffer();
+    int previousOffset = 0;
+    for (int i = 0; i < regions.length; i++) {
+      NavigationRegion region = regions[i];
+      int offset = mapper.map(region.offset);
+      int length = region.length;
+      if (offset > previousOffset) {
+        // Write a non-target region.
+        navContent.write(content.substring(previousOffset, offset));
+        if (region is NavigationSource) {
+          if (i + 1 < regions.length &&
+              regions[i + 1].offset == region.offset) {
+            NavigationTarget target = region.target;
+            if (target == regions[i + 1]) {
+              // Add a target region. We skip the source because it links to
+              // itself, which is pointless.
+              navContent.write('<a id="o${region.offset}">');
+              navContent.write(content.substring(offset, offset + length));
+              navContent.write('</a>');
+            } else {
+              // Add a source and target region.
+              // TODO(brianwilkerson) Map the target's file path to the path of
+              //  the corresponding html file. I'd like to do this by adding a
+              //  `FilePathMapper` object so that it can't become inconsistent
+              //  with the code used to decide where to write the html.
+              String htmlPath = pathMapper.map(target.filePath);
+              navContent.write('<a id="o${region.offset}" ');
+              navContent.write('href="$htmlPath#o${target.offset}">');
+              navContent.write(content.substring(offset, offset + length));
+              navContent.write('</a>');
+            }
+            i++;
+          } else {
+            // Add a source region.
+            NavigationTarget target = region.target;
+            String htmlPath = pathMapper.map(target.filePath);
+            navContent.write('<a href="$htmlPath#o${target.offset}">');
+            navContent.write(content.substring(offset, offset + length));
+            navContent.write('</a>');
+          }
+        } else {
+          // Add a target region.
+          navContent.write('<a id="o${region.offset}">');
+          navContent.write(content.substring(offset, offset + length));
+          navContent.write('</a>');
+        }
+        previousOffset = offset + length;
+      }
+    }
+    if (previousOffset < content.length) {
+      // Last non-target region.
+      navContent.write(content.substring(previousOffset));
+    }
+    return navContent.toString();
+  }
+
+  /// Return a list of Mustache context, based on the [unitInfo] for both
+  /// unmodified and modified regions:
+  ///
+  /// * 'modified': Whether this region represents modified source, or
+  ///   unmodified.
+  /// * 'content': The textual content of this region.
+  /// * 'explanation': The Mustache context for the tooltip explaining why the
+  ///   content in this region was modified.
+  List<Map> _computeRegions(UnitInfo unitInfo) {
+    String content = unitInfo.content;
+    List<Map> regions = [];
+    int previousOffset = 0;
+    for (var region in unitInfo.regions) {
+      int offset = region.offset;
+      int length = region.length;
+      if (offset > previousOffset) {
+        // Display a region of unmodified content.
+        regions.add({
+          'modified': false,
+          'content': content.substring(previousOffset, offset),
+        });
+        previousOffset = offset + length;
+      }
+      List<Map> details = [];
+      for (var detail in region.details) {
+        details.add({
+          'description': detail.description,
+          'target': _uriForTarget(detail.target),
+        });
+      }
+      regions.add({
+        'modified': true,
+        'content': content.substring(offset, offset + length),
+        'explanation': region.explanation,
+        'details': details,
+      });
+    }
+    if (previousOffset < content.length) {
+      // Last region of unmodified content.
+      regions.add({
+        'modified': false,
+        'content': content.substring(previousOffset),
+      });
+    }
+    return regions;
+  }
+
+  /// Return the URL that will navigate to the given [target].
+  String _uriForTarget(NavigationTarget target) {
+    path.Context pathContext = migrationInfo.pathContext;
+    String targetPath = pathContext.setExtension(target.filePath, '.html');
+    String sourceDir = pathContext.dirname(unitInfo.path);
+    String relativePath = pathContext.relative(targetPath, from: sourceDir);
+    return '$relativePath#o${target.offset.toString()}';
+  }
+}
+
+/// A class storing rendering information for an entire migration report.
+///
+/// This generally provides one [InstrumentationRenderer] (for one library)
+/// with information about the rest of the libraries represented in the
+/// instrumentation output.
+class MigrationInfo {
+  /// The information about the compilation units that are are migrated.
+  final List<UnitInfo> units;
+
+  /// The resource provider's path context.
+  final path.Context pathContext;
+
+  /// The filesystem root used to create relative paths for each unit.
+  final String includedRoot;
+
+  MigrationInfo(this.units, this.pathContext, this.includedRoot);
+
+  /// The path to the highlight.js script, relative to [unitInfo].
+  String highlightJsPath(UnitInfo unitInfo) =>
+      pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
+          from: pathContext.dirname(unitInfo.path));
+
+  /// The path to the highlight.js stylesheet, relative to [unitInfo].
+  String highlightStylePath(UnitInfo unitInfo) =>
+      pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
+          from: pathContext.dirname(unitInfo.path));
+
+  /// Generate mustache context for unit links, for navigation in the
+  /// instrumentation document for [thisUnit].
+  List<Map<String, Object>> unitLinks(UnitInfo thisUnit) {
+    return [
+      for (var unit in units)
+        {
+          'name': _computeName(unit),
+          'isLink': unit != thisUnit,
+          if (unit != thisUnit) 'href': _pathTo(target: unit, source: thisUnit)
+        }
+    ];
+  }
+
+  /// Return the path to [unit] from [includedRoot], to be used as a display
+  /// name for a library.
+  String _computeName(UnitInfo unit) =>
+      pathContext.relative(unit.path, from: includedRoot);
+
+  /// The path to [target], relative to [from].
+  String _pathTo({@required UnitInfo target, @required UnitInfo source}) {
+    String targetPath = pathContext.setExtension(target.path, '.html');
+    String sourceDir = pathContext.dirname(source.path);
+    return pathContext.relative(targetPath, from: sourceDir);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
index 7a66011..57f6002 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
@@ -15,19 +15,35 @@
   LibraryInfo(this.units);
 }
 
+/// A location from or to which a user might want to navigate.
+abstract class NavigationRegion {
+  /// The offset of the region.
+  final int offset;
+
+  /// The length of the region.
+  final int length;
+
+  /// Initialize a newly created link.
+  NavigationRegion(this.offset, this.length);
+}
+
+/// A location from which a user might want to navigate.
+class NavigationSource extends NavigationRegion {
+  /// The target to which the user should be navigated.
+  final NavigationTarget target;
+
+  /// Initialize a newly created link.
+  NavigationSource(int offset, int length, this.target) : super(offset, length);
+}
+
 /// A location to which a user might want to navigate.
-class NavigationTarget {
+class NavigationTarget extends NavigationRegion {
   /// The file containing the anchor.
   final String filePath;
 
-  /// The offset of the anchor.
-  final int offset;
-
-  /// The length of the anchor.
-  final int length;
-
   /// Initialize a newly created anchor.
-  NavigationTarget(this.filePath, this.offset, this.length);
+  NavigationTarget(this.filePath, int offset, int length)
+      : super(offset, length);
 
   @override
   int get hashCode => JenkinsSmiHash.hash3(filePath.hashCode, offset, length);
@@ -85,6 +101,10 @@
   /// them. The offsets in these regions are offsets into the post-edit content.
   final List<RegionInfo> regions = [];
 
+  /// The navigation sources that are located in this file. The offsets in these
+  /// sources are offsets into the pre-edit content.
+  List<NavigationSource> sources;
+
   /// The navigation targets that are located in this file. The offsets in these
   /// targets are offsets into the pre-edit content.
   final Set<NavigationTarget> targets = {};
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
new file mode 100644
index 0000000..f6939c0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:path/path.dart' as path;
+
+/// An object that can map the file paths of analyzed files to the file paths of
+/// the HTML files used to view the content of those files.
+class PathMapper {
+  /// The resource provider used to map paths.
+  ResourceProvider provider;
+
+  /// The absolute path of the folder that should contain all of the generated
+  /// HTML files.
+  final String outputFolder;
+
+  /// The root of the package containing the files being migrated.
+  final String packageRoot;
+
+  /// A table mapping the file paths of analyzed files to the file paths of the
+  /// HTML files used to view the content of those files.
+  final Map<String, String> pathMap = {};
+
+  /// The index to be used when creating the next synthetic file name.
+  int nextIndex = 1;
+
+  /// Initialize a newly created path mapper.
+  PathMapper(this.provider, this.outputFolder, this.packageRoot);
+
+  /// Return the path of the HTML file used to view the content of the analyzed
+  /// file with the given [path].
+  String map(String path) {
+    return pathMap.putIfAbsent(path, () => _computePathFor(path));
+  }
+
+  /// Return the path of the HTML file corresponding to the Dart file with the
+  /// given [path].
+  String _computePathFor(String filePath) {
+    path.Context context = provider.pathContext;
+    if (context.isWithin(packageRoot, filePath)) {
+      String packageParent = context.dirname(packageRoot);
+      String relative = context.relative(filePath, from: packageParent);
+      return context.join(
+          outputFolder, context.setExtension(relative, '.html'));
+    }
+    // TODO(brianwilkerson) Find a better mapping algorithm, that would produce
+    //  a more readable URI. For example, have other packages and the sdk be
+    //  parallel to the directory containing the files for the library being
+    //  migrated.
+    return context.join(outputFolder, 'f${nextIndex++}.html');
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index 3b1d28a..995aa40 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -58,6 +58,10 @@
     final renameOptionsSupport =
         params.capabilities.textDocument?.rename?.prepareSupport ?? false;
 
+    final dynamicTextSyncRegistration = params
+            .capabilities.textDocument?.synchronization?.dynamicRegistration ??
+        false;
+
     // When adding new capabilities to the server that may apply to specific file
     // types, it's important to update
     // [IntializedMessageHandler._performDynamicRegistration()] to notify
@@ -66,8 +70,13 @@
     // requests where we have only partial support for some types).
     server.capabilities = new ServerCapabilities(
         Either2<TextDocumentSyncOptions, num>.t1(new TextDocumentSyncOptions(
-          true,
-          TextDocumentSyncKind.Incremental,
+          // The open/close and sync kind flags are registered dynamically if the
+          // client supports them, so these static registrations are based on whether
+          // the client supports dynamic registration.
+          dynamicTextSyncRegistration ? false : true,
+          dynamicTextSyncRegistration
+              ? TextDocumentSyncKind.None
+              : TextDocumentSyncKind.Incremental,
           false,
           false,
           null,
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 6c51810..efbaa0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -134,9 +134,7 @@
   static const FLUTTER_MOVE_UP =
       const AssistKind('dart.assist.flutter.move.up', 30, "Move widget up");
   static const FLUTTER_REMOVE_WIDGET = const AssistKind(
-      'dart.assist.flutter.removeWidget',
-      30,
-      "Replace widget with its children");
+      'dart.assist.flutter.removeWidget', 30, "Remove this widget");
   static const FLUTTER_SWAP_WITH_CHILD = const AssistKind(
       'dart.assist.flutter.swap.withChild', 30, "Swap with child");
   static const FLUTTER_SWAP_WITH_PARENT = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index 32e627e..3c3870b 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -65,6 +65,109 @@
       (session.analysisContext.analysisOptions as AnalysisOptionsImpl)
           .experimentStatus;
 
+  Future<ChangeBuilder> createBuilder_addDiagnosticPropertyReference() async {
+    final node = this.node;
+    if (node is! SimpleIdentifier) {
+      _coverageMarker();
+      return null;
+    }
+    SimpleIdentifier name = node;
+    final parent = node.parent;
+
+    DartType type;
+
+    // Getter.
+    if (parent is MethodDeclaration) {
+      MethodDeclaration methodDeclaration = parent;
+      var element = methodDeclaration.declaredElement;
+      if (element is PropertyAccessorElement) {
+        PropertyAccessorElement propertyAccessor = element;
+        type = propertyAccessor.returnType;
+      }
+      // Field.
+    } else if (parent is VariableDeclaration) {
+      VariableDeclaration variableDeclaration = parent;
+      final element = variableDeclaration.declaredElement;
+      if (element is FieldElement) {
+        FieldElement fieldElement = element;
+        type = fieldElement.type;
+      }
+    }
+
+    if (type == null) {
+      return null;
+    }
+
+    var constructorInvocation;
+    if (type.isDartCoreBool) {
+      constructorInvocation = 'DiagnosticsProperty<bool>';
+    } else if (type.isDartCoreInt) {
+      constructorInvocation = 'IntProperty';
+    } else if (type.isDartCoreDouble) {
+      constructorInvocation = 'DoubleProperty';
+    } else if (type.isDartCoreString) {
+      constructorInvocation = 'StringProperty';
+    } else if (isEnum(type)) {
+      constructorInvocation = 'EnumProperty';
+    }
+
+    // todo (pq): migrate type string generation to within change and use DartEditBuilder.writeType
+
+    if (constructorInvocation == null) {
+      return null;
+    }
+
+    ClassDeclaration classDeclaration =
+        parent.thisOrAncestorOfType<ClassDeclaration>();
+    final debugFillProperties =
+        classDeclaration.getMethod('debugFillProperties');
+    if (debugFillProperties != null) {
+      final body = debugFillProperties.body;
+      if (body is BlockFunctionBody) {
+        BlockFunctionBody functionBody = body;
+
+        var offset;
+        var prefix;
+        if (functionBody.block.statements.isEmpty) {
+          offset = functionBody.block.leftBracket.offset;
+          prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
+        } else {
+          offset = functionBody.block.statements.last.endToken.offset;
+          prefix = utils.getLinePrefix(offset);
+        }
+
+        var parameters = debugFillProperties.parameters.parameters;
+        var propertiesBuilderName;
+        for (var parameter in parameters) {
+          if (parameter is SimpleFormalParameter) {
+            final type = parameter.type;
+            if (type is TypeName) {
+              if (type.name.name == 'DiagnosticPropertiesBuilder') {
+                propertiesBuilderName = parameter.identifier.name;
+                break;
+              }
+            }
+          }
+        }
+        if (propertiesBuilderName == null) {
+          return null;
+        }
+
+        final changeBuilder = _newDartChangeBuilder();
+        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+          builder.addInsertion(utils.getLineNext(offset),
+              (DartEditBuilder builder) {
+            builder.write(
+                "$prefix$propertiesBuilderName.add($constructorInvocation('${name.name}', ${name.name}));$eol");
+          });
+        });
+        return changeBuilder;
+      }
+    }
+
+    return null;
+  }
+
   Future<ChangeBuilder>
       createBuilder_addTypeAnnotation_DeclaredIdentifier() async {
     DeclaredIdentifier declaredIdentifier =
@@ -860,46 +963,6 @@
     return changeBuilder;
   }
 
-  Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
-    NamedExpression childProp = flutter.findNamedExpression(node, 'child');
-    if (childProp == null) {
-      childProp = flutter.findNamedExpression(node, 'children');
-    }
-    if (childProp == null) {
-      return null;
-    }
-
-    var parent = childProp.parent?.parent;
-    if (parent is! InstanceCreationExpression ||
-        !flutter.isWidgetCreation(parent)) {
-      return null;
-    }
-
-    InstanceCreationExpression creationExpression = parent;
-    var args = creationExpression.argumentList;
-
-    var last = args.arguments.last;
-    if (last == childProp) {
-      // Already sorted.
-      return null;
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      var start = childProp.beginToken.previous.end;
-      var end = childProp.endToken.next.end;
-      var childRange = range.startOffsetEndOffset(start, end);
-
-      var childText = utils.getRangeText(childRange);
-      builder.addSimpleReplacement(childRange, '');
-      builder.addSimpleInsertion(last.end + 1, childText);
-
-      changeBuilder.setSelection(new Position(file, last.end + 1));
-    });
-
-    return changeBuilder;
-  }
-
   /// todo (pq): unify with similar behavior in fix.
   Future<ChangeBuilder> createBuilder_removeTypeAnnotation() async {
     VariableDeclarationList declarationList =
@@ -945,6 +1008,46 @@
     return changeBuilder;
   }
 
+  Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
+    NamedExpression childProp = flutter.findNamedExpression(node, 'child');
+    if (childProp == null) {
+      childProp = flutter.findNamedExpression(node, 'children');
+    }
+    if (childProp == null) {
+      return null;
+    }
+
+    var parent = childProp.parent?.parent;
+    if (parent is! InstanceCreationExpression ||
+        !flutter.isWidgetCreation(parent)) {
+      return null;
+    }
+
+    InstanceCreationExpression creationExpression = parent;
+    var args = creationExpression.argumentList;
+
+    var last = args.arguments.last;
+    if (last == childProp) {
+      // Already sorted.
+      return null;
+    }
+
+    var changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      var start = childProp.beginToken.previous.end;
+      var end = childProp.endToken.next.end;
+      var childRange = range.startOffsetEndOffset(start, end);
+
+      var childText = utils.getRangeText(childRange);
+      builder.addSimpleReplacement(childRange, '');
+      builder.addSimpleInsertion(last.end + 1, childText);
+
+      changeBuilder.setSelection(new Position(file, last.end + 1));
+    });
+
+    return changeBuilder;
+  }
+
   @protected
   Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
     Future<ChangeBuilder> doStatement(DoStatement node) async {
@@ -1105,6 +1208,11 @@
     return null;
   }
 
+  bool isEnum(DartType type) {
+    final element = type.element;
+    return element is ClassElement && element.isEnum;
+  }
+
   @protected
   bool setupCompute() {
     final locator = NodeLocator(selectionOffset, selectionEnd);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index b2bc9a3..6a005f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -142,6 +142,10 @@
       const FixKind('ADD_CONST', 50, "Add 'const' modifier");
   static const ADD_CURLY_BRACES =
       const FixKind('ADD_CURLY_BRACES', 50, "Add curly braces");
+  static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE = const FixKind(
+      'ADD_DIAGNOSTIC_PROPERTY_REFERENCE',
+      50,
+      "Add a debug reference to this property");
   static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
       'ADD_FIELD_FORMAL_PARAMETERS', 70, "Add final field formal parameters");
   static const ADD_MISSING_ENUM_CASE_CLAUSES = const FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 7dff396..801408f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -628,6 +628,9 @@
       if (name == LintNames.curly_braces_in_flow_control_structures) {
         await _addFix_addCurlyBraces();
       }
+      if (name == LintNames.diagnostic_describe_all_properties) {
+        await _addFix_addDiagnosticPropertyReference();
+      }
       if (name == LintNames.empty_catches) {
         await _addFix_removeEmptyCatch();
       }
@@ -781,6 +784,12 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.ADD_CURLY_BRACES);
   }
 
+  Future<void> _addFix_addDiagnosticPropertyReference() async {
+    final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
+    _addFixFromBuilder(
+        changeBuilder, DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
+  }
+
   Future<void> _addFix_addExplicitCast() async {
     if (coveredNode is! Expression) {
       return;
@@ -3525,6 +3534,47 @@
     }
   }
 
+  Future<void> _addFix_removeUnusedElement() async {
+    final sourceRanges = <SourceRange>[];
+    final referencedNode = node.parent;
+    if (referencedNode is ClassDeclaration ||
+        referencedNode is EnumDeclaration ||
+        referencedNode is FunctionDeclaration ||
+        referencedNode is FunctionTypeAlias ||
+        referencedNode is MethodDeclaration ||
+        referencedNode is VariableDeclaration) {
+      final element = referencedNode is Declaration
+          ? referencedNode.declaredElement
+          : (referencedNode as NamedCompilationUnitMember).declaredElement;
+      final references = _findAllReferences(unit, element);
+      // todo (pq): consider filtering for references that are limited to within the class.
+      if (references.length == 1) {
+        var sourceRange;
+        if (referencedNode is VariableDeclaration) {
+          VariableDeclarationList parent = referencedNode.parent;
+          if (parent.variables.length == 1) {
+            sourceRange = utils.getLinesRange(range.node(parent.parent));
+          } else {
+            sourceRange = range.nodeInList(parent.variables, node);
+          }
+        } else {
+          sourceRange = utils.getLinesRange(range.node(referencedNode));
+        }
+        sourceRanges.add(sourceRange);
+      }
+    }
+
+    if (sourceRanges.isNotEmpty) {
+      final changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        for (var sourceRange in sourceRanges) {
+          builder.addDeletion(sourceRange);
+        }
+      });
+      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
+    }
+  }
+
   Future<void> _addFix_removeUnusedField() async {
     final declaration = node.parent;
     if (declaration is! VariableDeclaration) {
@@ -3588,47 +3638,6 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_FIELD);
   }
 
-  Future<void> _addFix_removeUnusedElement() async {
-    final sourceRanges = <SourceRange>[];
-    final referencedNode = node.parent;
-    if (referencedNode is ClassDeclaration ||
-        referencedNode is EnumDeclaration ||
-        referencedNode is FunctionDeclaration ||
-        referencedNode is FunctionTypeAlias ||
-        referencedNode is MethodDeclaration ||
-        referencedNode is VariableDeclaration) {
-      final element = referencedNode is Declaration
-          ? referencedNode.declaredElement
-          : (referencedNode as NamedCompilationUnitMember).declaredElement;
-      final references = _findAllReferences(unit, element);
-      // todo (pq): consider filtering for references that are limited to within the class.
-      if (references.length == 1) {
-        var sourceRange;
-        if (referencedNode is VariableDeclaration) {
-          VariableDeclarationList parent = referencedNode.parent;
-          if (parent.variables.length == 1) {
-            sourceRange = utils.getLinesRange(range.node(parent.parent));
-          } else {
-            sourceRange = range.nodeInList(parent.variables, node);
-          }
-        } else {
-          sourceRange = utils.getLinesRange(range.node(referencedNode));
-        }
-        sourceRanges.add(sourceRange);
-      }
-    }
-
-    if (sourceRanges.isNotEmpty) {
-      final changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        for (var sourceRange in sourceRanges) {
-          builder.addDeletion(sourceRange);
-        }
-      });
-      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
-    }
-  }
-
   Future<void> _addFix_removeUnusedImport() async {
     // prepare ImportDirective
     ImportDirective importDirective =
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index b3ee6f1..fbd3a46 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -20,6 +20,8 @@
   static const String await_only_futures = 'await_only_futures';
   static const String curly_braces_in_flow_control_structures =
       'curly_braces_in_flow_control_structures';
+  static const String diagnostic_describe_all_properties =
+      'diagnostic_describe_all_properties';
   static const String empty_catches = 'empty_catches';
   static const String empty_constructor_bodies = 'empty_constructor_bodies';
   static const String empty_statements = 'empty_statements';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 3feab8b..ba6c8a3 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -381,7 +381,7 @@
     for (var invocation in collector.invocations) {
       List<Expression> arguments = invocation.argumentList.arguments;
       builder.addReplacement(range.node(invocation), (builder) {
-        builder.write('new $name(');
+        builder.write('$name(');
 
         // Insert field references (as named arguments).
         // Ensure that invocation arguments are named.
@@ -545,7 +545,7 @@
 
   /// Write instantiation of the new widget class.
   void _writeWidgetInstantiation(DartEditBuilder builder) {
-    builder.write('new $name(');
+    builder.write('$name(');
 
     for (var parameter in _parameters) {
       if (parameter != _parameters.first) {
diff --git a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
index 7865f34..7056d15 100644
--- a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
+++ b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -21,61 +22,73 @@
   /// library.
   // TODO(srawlins): Add tests for navigation links, which use multiple
   // libraries.
-  String renderLibrary(LibraryInfo libraryInfo) {
-    MigrationInfo migrationInfo =
-        MigrationInfo([libraryInfo], resourceProvider.pathContext, '/project');
-    return InstrumentationRenderer(libraryInfo, migrationInfo).render();
+  List<String> renderLibrary(LibraryInfo libraryInfo) {
+    String packageRoot = resourceProvider.convertPath('/package');
+    String outputDir = resourceProvider.convertPath('/output');
+    MigrationInfo migrationInfo = MigrationInfo(
+        libraryInfo.units, resourceProvider.pathContext, packageRoot);
+    List<String> contents = [];
+    for (UnitInfo unitInfo in libraryInfo.units) {
+      contents.add(InstrumentationRenderer(unitInfo, migrationInfo,
+              PathMapper(resourceProvider, outputDir, packageRoot))
+          .render());
+    }
+    return contents;
   }
 
   test_outputContainsEachPath() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'int? a = null;',
+      unit('/package/lib/a.dart', 'int? a = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
-      unit('/lib/part1.dart', 'int? b = null;',
+      unit('/package/lib/part1.dart', 'int? b = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
-      unit('/lib/part2.dart', 'int? c = null;',
+      unit('/package/lib/part2.dart', 'int? c = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
     ]);
-    String output = renderLibrary(info);
-    expect(output, contains('<h2>/lib/a.dart</h2>'));
-    expect(output, contains('<h2>/lib/part1.dart</h2>'));
-    expect(output, contains('<h2>/lib/part2.dart</h2>'));
+    List<String> contents = renderLibrary(info);
+    expect(contents[0], contains(resourceProvider.convertPath('lib/a.dart')));
+    expect(
+        contents[1], contains(resourceProvider.convertPath('lib/part1.dart')));
+    expect(
+        contents[2], contains(resourceProvider.convertPath('lib/part2.dart')));
   }
 
   test_outputContainsEscapedHtml() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'List<String>? a = null;',
+      unit('/package/lib/a.dart', 'List<String>? a = null;',
           regions: [RegionInfo(12, 1, 'null was assigned', [])]),
     ]);
-    String output = renderLibrary(info);
+    String output = renderLibrary(info)[0];
     expect(
         output,
         contains('List&lt;String&gt;<span class="region">?'
-            '<span class="tooltip">null was assigned</span></span> a = null;'));
+            '<span class="tooltip">null was assigned<ul></ul></span></span> '
+            'a = null;'));
   }
 
   test_outputContainsEscapedHtml_ampersand() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'bool a = true && false;', regions: []),
+      unit('/package/lib/a.dart', 'bool a = true && false;', regions: []),
     ]);
-    String output = renderLibrary(info);
+    String output = renderLibrary(info)[0];
     expect(output, contains('bool a = true &amp;&amp; false;'));
   }
 
   test_outputContainsModifiedAndUnmodifiedRegions() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'int? a = null;',
+      unit('/package/lib/a.dart', 'int? a = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
     ]);
-    String output = renderLibrary(info);
+    String output = renderLibrary(info)[0];
     expect(
         output,
         contains('int<span class="region">?'
-            '<span class="tooltip">null was assigned</span></span> a = null;'));
+            '<span class="tooltip">null was assigned<ul></ul></span></span> '
+            'a = null;'));
   }
 
   UnitInfo unit(String path, String content, {List<RegionInfo> regions}) {
-    return UnitInfo(path)
+    return UnitInfo(resourceProvider.convertPath(path))
       ..content = content
       ..regions.addAll(regions);
   }
diff --git a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
index 40e2ff6..799c69e 100644
--- a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
@@ -15,6 +15,9 @@
 
 @reflectiveTest
 class DiagnosticTest extends AbstractLspAnalysisServerIntegrationTest {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_initialAnalysis() async {
     newFile(mainFilePath, content: 'String a = 1;');
 
@@ -30,6 +33,9 @@
     expect(diagnostic.range.end.character, equals(12));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_lints() async {
     newFile(mainFilePath, content: '''main() async => await 1;''');
     newFile(analysisOptionsPath, content: '''
diff --git a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
index 8d364dc..91f75bc 100644
--- a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
@@ -17,6 +17,9 @@
 
 @reflectiveTest
 class InitializationTest extends AbstractLspAnalysisServerIntegrationTest {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_initialize_invalidParams() async {
     final params = {'processId': 'invalid'};
     final request = new RequestMessage(
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index e1eeec2..23317b4 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -144,11 +144,24 @@
 
     String dartBinary = Platform.executable;
 
-    // TODO(dantup): The other servers integration tests can run with a snapshot
-    // which is much faster - we may wish to investigate doing the same here.
-    final rootDir =
-        findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
-    final serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+    final bool useSnapshot = true;
+    String serverPath;
+
+    if (useSnapshot) {
+      // Look for snapshots/analysis_server.dart.snapshot.
+      serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+          'snapshots', 'analysis_server.dart.snapshot'));
+
+      if (!FileSystemEntity.isFileSync(serverPath)) {
+        // Look for dart-sdk/bin/snapshots/analysis_server.dart.snapshot.
+        serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+            'dart-sdk', 'bin', 'snapshots', 'analysis_server.dart.snapshot'));
+      }
+    } else {
+      final rootDir =
+          findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+      serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+    }
 
     final arguments = [serverPath, '--lsp', '--suppress-analytics'];
     _process = await Process.start(dartBinary, arguments);
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
index 0b73ad4..fd7e279 100644
--- a/pkg/analysis_server/test/integration/lsp_server/server_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
@@ -18,6 +18,9 @@
 
 @reflectiveTest
 class ServerTest extends AbstractLspAnalysisServerIntegrationTest {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_diagnosticServer() async {
     await initialize();
 
@@ -38,6 +41,9 @@
     expect(responseBody, contains('<title>Analysis Server</title>'));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_inintializedWithShutdown() async {
     await initialize();
     await sendShutdown();
@@ -53,6 +59,9 @@
     expect(exitCode, equals(0));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_initializedWithoutShutdown() async {
     // Send a request that we can wait for, to ensure the server is fully ready
     // before we send exit. Otherwise the exit notification won't be handled for
@@ -70,6 +79,9 @@
     expect(exitCode, equals(1));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_uninintializedWithShutdown() async {
     await sendShutdown();
     sendExit();
@@ -84,6 +96,9 @@
     expect(exitCode, equals(0));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_uninitializedWithoutShutdown() async {
     // This tests the same as test_exit_withoutShutdown but without sending
     // initialize. It can't be as strict with the timeout as the server may take
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index 55d5140..6a1cd63 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -112,7 +112,7 @@
   Widget build(BuildContext context) {
     return new Row(
       children: <Widget>[
-        new NewWidget(),
+        NewWidget(),
         new Text('CCC'),
         new Text('DDD'),
       ],
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 648b7ed..7de98f7 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -208,9 +208,23 @@
     });
 
     // Initialize with no dynamic registrations advertised.
-    await initialize();
+    final initResponse = await initialize();
     await pumpEventQueue();
 
+    // When dynamic registration is not supported, we will always statically
+    // request text document open/close and incremental updates.
+    InitializeResult initResult = initResponse.result;
+    expect(initResult.capabilities, isNotNull);
+    expect(initResult.capabilities.textDocumentSync, isNotNull);
+    initResult.capabilities.textDocumentSync.map(
+      (options) {
+        expect(options.openClose, isTrue);
+        expect(options.change, equals(TextDocumentSyncKind.Incremental));
+      },
+      (_) =>
+          throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+    );
+
     expect(didGetRegisterCapabilityRequest, isFalse);
   }
 
@@ -237,7 +251,8 @@
     // for ex including analysis_options.yaml in text synchronization but not
     // for hovers.
     List<Registration> registrations;
-    await handleExpectedRequest<void, RegistrationParams, void>(
+    final initResponse =
+        await handleExpectedRequest<ResponseMessage, RegistrationParams, void>(
       Method.client_registerCapability,
       () => initialize(
           // Support dynamic registration for both text sync + hovers.
@@ -248,6 +263,21 @@
           registrations = registrationParams.registrations,
     );
 
+    // Because we support dynamic registration for synchronisation, we won't send
+    // static registrations for them.
+    // https://github.com/dart-lang/sdk/issues/38490
+    InitializeResult initResult = initResponse.result;
+    expect(initResult.capabilities, isNotNull);
+    expect(initResult.capabilities.textDocumentSync, isNotNull);
+    initResult.capabilities.textDocumentSync.map(
+      (options) {
+        expect(options.openClose, isFalse);
+        expect(options.change, equals(TextDocumentSyncKind.None));
+      },
+      (_) =>
+          throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+    );
+
     // Should container Hover, DidOpen, DidClose, DidChange.
     expect(registrations, hasLength(4));
     final hover =
diff --git a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
index 580a076..1ed98d3 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
@@ -121,7 +121,7 @@
   Widget build(BuildContext context) {
     return new Row(
       children: <Widget>[
-        new Test(),
+        Test(),
         new Text('CCC'),
         new Text('DDD'),
       ],
@@ -173,7 +173,7 @@
   Widget foo() {
     return new Row(
       children: <Widget>[
-        new Test(),
+        Test(),
         new Text('BBB'),
       ],
     );
@@ -214,7 +214,7 @@
 class MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Test();
+    return Test();
   }
 }
 
@@ -249,7 +249,7 @@
 import 'package:flutter/material.dart';
 
 Widget main() {
-  return new Test();
+  return Test();
 }
 
 class Test extends StatelessWidget {
@@ -301,7 +301,7 @@
 Widget main() {
   return new Row(
     children: <Widget>[
-      new Test(),
+      Test(),
       new Text('BBB'),
     ],
   );
@@ -409,7 +409,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(c: c);
+    return Test(c: c);
   }
 }
 
@@ -462,7 +462,7 @@
 class MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Test();
+    return Test();
   }
 }
 
@@ -524,8 +524,8 @@
     int bar = 1;
     return new Row(
       children: <Widget>[
-        new Test(foo: foo, p1: 'aaa', p2: bar),
-        new Test(foo: foo, p1: 'bbb', p2: 2),
+        Test(foo: foo, p1: 'aaa', p2: bar),
+        Test(foo: foo, p1: 'bbb', p2: 2),
       ],
     );
   }
@@ -596,8 +596,8 @@
     int bar = 1;
     return new Row(
       children: <Widget>[
-        new Test(foo: foo, p1: 'aaa', p2: bar),
-        new Test(foo: foo, p1: 'bbb', p2: 2),
+        Test(foo: foo, p1: 'aaa', p2: bar),
+        Test(foo: foo, p1: 'bbb', p2: 2),
       ],
     );
   }
@@ -651,7 +651,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(field: field);
+    return Test(field: field);
   }
 }
 
@@ -703,7 +703,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(c: c);
+    return Test(c: c);
   }
 }
 
@@ -747,7 +747,7 @@
 class MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Test();
+    return Test();
   }
 }
 
@@ -853,7 +853,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(c: c);
+    return Test(c: c);
   }
 }
 
@@ -919,7 +919,7 @@
   @override
   Widget build(BuildContext context) {
     String local;
-    return new Test(local: local);
+    return Test(local: local);
   }
 }
 
@@ -987,7 +987,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(field: _field);
+    return Test(field: _field);
   }
 }
 
@@ -1033,7 +1033,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(field: field, field2: _field);
+    return Test(field: field, field2: _field);
   }
 }
 
@@ -1086,7 +1086,7 @@
   @override
   Widget build(BuildContext context) {
     String local;
-    return new Test(field: field, local: local);
+    return Test(field: field, local: local);
   }
 }
 
@@ -1157,7 +1157,7 @@
   var index = 0;
   var a = 'a $index';
 // start
-  return new Test(index: index, a: a);
+  return Test(index: index, a: a);
 // end
 }
 
diff --git a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
index 408a7a7..a2b0dcc 100644
--- a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
+++ b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
@@ -136,11 +136,11 @@
     Folder outputDir = getFolder('/outputDir');
     await performFix(included: [projectPath], outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(getFile('/outputDir/bin/bin.html').exists, isTrue);
-    expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
-    expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
-    expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
-    expect(getFile('/outputDir/test/test.html').exists, isTrue);
+    expect(getFile('/outputDir/project/bin/bin.html').exists, isTrue);
+    expect(getFile('/outputDir/project/lib/lib1.html').exists, isTrue);
+    expect(getFile('/outputDir/project/lib/lib2.html').exists, isTrue);
+    expect(getFile('/outputDir/project/lib/src/lib3.html').exists, isTrue);
+    expect(getFile('/outputDir/project/test/test.html').exists, isTrue);
   }
 
   test_outputDirContainsFilesRootedInASubdirectory() async {
@@ -150,9 +150,9 @@
         included: [context.join(projectPath, 'lib')],
         outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(getFile('/outputDir/lib1.html').exists, isTrue);
-    expect(getFile('/outputDir/lib2.html').exists, isTrue);
-    expect(getFile('/outputDir/src/lib3.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
   }
 
   test_outputDirContainsFilesRootedInParentOfSingleFile() async {
@@ -162,6 +162,11 @@
         included: [context.join(projectPath, 'lib', 'lib2.dart')],
         outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(outputDir.getChildAssumingFile('lib2.html').exists, isTrue);
+    expect(
+        outputDir
+            .getChildAssumingFolder('lib')
+            .getChildAssumingFile('lib2.html')
+            .exists,
+        isTrue);
   }
 }
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
index ca0162f..d349e0d 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
@@ -25,7 +25,7 @@
 class InfoBuilderTest extends AbstractAnalysisTest {
   /// The information produced by the InfoBuilder, or `null` if [buildInfo] has
   /// not yet completed.
-  List<LibraryInfo> infos;
+  List<UnitInfo> infos;
 
   /// Use the InfoBuilder to build information. The information will be stored
   /// in [infos].
@@ -53,7 +53,7 @@
     infos = await builder.explainMigration();
   }
 
-  test_parameter_nullableFromInvocation() async {
+  test_parameter_nullable_fromInvocation() async {
     addTestFile('''
 void f(String s) {}
 void g() {
@@ -62,9 +62,7 @@
 ''');
     await buildInfo();
     expect(infos, hasLength(1));
-    List<UnitInfo> units = infos[0].units;
-    expect(units, hasLength(1));
-    UnitInfo unit = units[0];
+    UnitInfo unit = infos[0];
     expect(unit.path, testFile);
     expect(unit.content, '''
 void f(String? s) {}
@@ -77,5 +75,37 @@
     RegionInfo region = regions[0];
     expect(region.offset, 13);
     expect(region.length, 1);
+    List<RegionDetail> details = region.details;
+    expect(details, hasLength(1));
+  }
+
+  test_parameter_nullable_fromOverriden() async {
+    addTestFile('''
+class A {
+  void m(p) {}
+}
+class B extends A {
+  void m(Object p) {}
+}
+''');
+    await buildInfo();
+    expect(infos, hasLength(1));
+    UnitInfo unit = infos[0];
+    expect(unit.path, testFile);
+    expect(unit.content, '''
+class A {
+  void m(p) {}
+}
+class B extends A {
+  void m(Object? p) {}
+}
+''');
+    List<RegionInfo> regions = unit.regions;
+    expect(regions, hasLength(1));
+    RegionInfo region = regions[0];
+    expect(region.offset, 62);
+    expect(region.length, 1);
+    List<RegionDetail> details = region.details;
+    expect(details, hasLength(1));
   }
 }
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index df7d05f..384cafc 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -202,6 +202,9 @@
         notificationManager, InstrumentationService.NULL_SERVICE);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_addPluginToContextRoot() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -233,6 +236,9 @@
 //    pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_broadcastRequest_many() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -259,6 +265,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_broadcastRequest_many_noContextRoot() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -283,6 +292,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_broadcastWatchEvent() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -306,6 +318,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_pluginsForContextRoot_multiple() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -333,6 +348,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_pluginsForContextRoot_one() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -349,6 +367,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_removedContextRoot() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -364,6 +385,9 @@
   }
 
   @TestTimeout(const Timeout.factor(4))
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_restartPlugins() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkg1Path = pkg1Dir.resolveSymbolicLinksSync();
@@ -514,6 +538,9 @@
 
 @reflectiveTest
 class PluginSessionFromDiskTest extends PluginTestSupport {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_start_notRunning() async {
     await withPlugin(test: (String pluginPath) async {
       String packagesPath = path.join(pluginPath, '.packages');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
new file mode 100644
index 0000000..13f5ab3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
@@ -0,0 +1,214 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AddDiagnosticPropertyReferenceTest);
+  });
+}
+
+@reflectiveTest
+class AddDiagnosticPropertyReferenceTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+  @override
+  String get lintCode => LintNames.diagnostic_describe_all_properties;
+
+  test_boolField_debugFillProperties() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool get absorbing => _absorbing;
+  bool _absorbing;
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool get absorbing => _absorbing;
+  bool _absorbing;
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+    properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+  }
+}
+''');
+  }
+
+  test_boolField_debugFillProperties_empty() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+  }
+}
+''');
+  }
+
+  test_boolField_debugFillProperties_empty_customParamName() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder props) {
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder props) {
+    props.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+  }
+}
+''');
+  }
+
+  test_boolGetter_debugFillProperties() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool get /*LINT*/absorbing => _absorbing;
+  bool _absorbing;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool get /*LINT*/absorbing => _absorbing;
+  bool _absorbing;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+  }
+}
+''');
+  }
+
+  test_doubleField_debugFillProperties() async {
+    await resolveTestUnit('''
+class A extends Widget {
+  double /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class A extends Widget {
+  double /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DoubleProperty('field', field));
+  }
+}
+''');
+  }
+
+  test_enumField_debugFillProperties() async {
+    await resolveTestUnit('''
+enum foo {bar}
+class A extends Widget {
+  foo /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+enum foo {bar}
+class A extends Widget {
+  foo /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(EnumProperty('field', field));
+  }
+}
+''');
+  }
+
+  test_intField_debugFillProperties() async {
+    await resolveTestUnit('''
+class A extends Widget {
+  int /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class A extends Widget {
+  int /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(IntProperty('field', field));
+  }
+}
+''');
+  }
+
+  test_stringField_debugFillProperties() async {
+    await resolveTestUnit('''
+class A extends Widget {
+  String /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class A extends Widget {
+  String /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(StringProperty('field', field));
+  }
+}
+''');
+  }
+
+  // todo (pq): tests for no debugFillProperties method
+  // todo (pq): consider a test for a body w/ no CR
+  // todo (pq): support for ColorProperty -- for Color
+  // todo (pq): support for IterableProperty -- any iterable
+  // todo (pq): support for TransformProperty -- Matrix4
+  // todo (pq): support for DiagnosticsProperty for any T that doesn't match one of the other cases
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 3509418..3c6ba74 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -8,6 +8,8 @@
 import 'add_await_test.dart' as add_await;
 import 'add_const_test.dart' as add_const;
 import 'add_curly_braces_test.dart' as add_curly_braces;
+import 'add_diagnostic_property_reference_test.dart'
+    as add_diagnostic_property_reference;
 import 'add_explicit_cast_test.dart' as add_explicit_cast;
 import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
 import 'add_missing_enum_case_clauses_test.dart'
@@ -140,6 +142,7 @@
     add_await.main();
     add_const.main();
     add_curly_braces.main();
+    add_diagnostic_property_reference.main();
     add_explicit_cast.main();
     add_field_formal_parameters.main();
     add_missing_enum_case_clauses.main();
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 3fa0592..59199b3 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -10,14 +10,10 @@
     # Ignoring "style" lint rules from pedantic for now. There are pre-existing
     # violations that need to be cleaned up. Each one can be cleaned up and
     # enabled according to the value provided.
-    avoid_init_to_null: ignore
     avoid_return_types_on_setters: ignore
     curly_braces_in_flow_control_structures: ignore
     empty_catches: ignore
     prefer_iterable_wheretype: ignore
-    prefer_contains: ignore
-    # TODO(srawlins): Fix existing violations!
-    no_duplicate_case_values: ignore
     # TODO(srawlins): At the time of writing, 230 violations in lib/. The fix
     # is mechanical, via `dartfmt --fix-named-default-separator`.
     prefer_equal_for_default_values: ignore
diff --git a/pkg/analyzer/lib/dart/analysis/context_locator.dart b/pkg/analyzer/lib/dart/analysis/context_locator.dart
index d2c4cd3..2211439 100644
--- a/pkg/analyzer/lib/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/dart/analysis/context_locator.dart
@@ -39,9 +39,9 @@
   List<AnalysisContext> locateContexts(
       {@required List<String> includedPaths,
       List<String> excludedPaths: const <String>[],
-      String optionsFile: null,
-      String packagesFile: null,
-      String sdkPath: null});
+      String optionsFile,
+      String packagesFile,
+      String sdkPath});
 
   /// Return a list of the context roots that should be used to analyze the
   /// files that are included by the list of [includedPaths] and not excluded by
@@ -57,7 +57,7 @@
   /// found by looking in the directories containing the context roots.
   List<ContextRoot> locateRoots(
       {@required List<String> includedPaths,
-      List<String> excludedPaths: null,
-      String optionsFile: null,
-      String packagesFile: null});
+      List<String> excludedPaths,
+      String optionsFile,
+      String packagesFile});
 }
diff --git a/pkg/analyzer/lib/exception/exception.dart b/pkg/analyzer/lib/exception/exception.dart
index e475c04..73b1a5d 100644
--- a/pkg/analyzer/lib/exception/exception.dart
+++ b/pkg/analyzer/lib/exception/exception.dart
@@ -21,7 +21,7 @@
    * Initialize a newly created exception to have the given [message] and
    * [cause].
    */
-  AnalysisException([this.message = 'Exception', this.cause = null]);
+  AnalysisException([this.message = 'Exception', this.cause]);
 
   String toString() {
     StringBuffer buffer = new StringBuffer();
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
index 5d3e616..2566e22 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -41,7 +41,7 @@
   /// The given [root] directory will be searched first. If no file is found and
   /// if [crawlUp] is `true`, then enclosing directories will be searched.
   File getOptionsFile(Folder root, {bool crawlUp: false}) {
-    Resource resource = null;
+    Resource resource;
     for (Folder folder = root; folder != null; folder = folder.parent) {
       resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
       if (resource.exists) {
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 4a58ff8..a1840b0 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -78,7 +78,7 @@
    * create their own drivers with the same tools, in theory. Here as a stopgap
    * until the official plugin API is complete
    */
-  static Function onCreateAnalysisDriver = null;
+  static Function onCreateAnalysisDriver;
 
   /**
    * The [ResourceProvider] by which paths are converted into [Resource]s.
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 71abce1..07a26ee 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -251,7 +251,7 @@
 
     // Check .packages and update target and actual URIs as appropriate.
     if (_packages != null && containedUri.scheme == 'package') {
-      Uri packageUri = null;
+      Uri packageUri;
       try {
         packageUri =
             _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 52a6a24..1f6826a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -76,9 +76,9 @@
   List<AnalysisContext> locateContexts(
       {@required List<String> includedPaths,
       List<String> excludedPaths: const <String>[],
-      String optionsFile: null,
-      String packagesFile: null,
-      String sdkPath: null}) {
+      String optionsFile,
+      String packagesFile,
+      String sdkPath}) {
     List<ContextRoot> roots = locateRoots(
         includedPaths: includedPaths,
         excludedPaths: excludedPaths,
@@ -120,9 +120,9 @@
   @override
   List<ContextRoot> locateRoots(
       {@required List<String> includedPaths,
-      List<String> excludedPaths: null,
-      String optionsFile: null,
-      String packagesFile: null}) {
+      List<String> excludedPaths,
+      String optionsFile,
+      String packagesFile}) {
     //
     // Compute the list of folders and files that are to be included.
     //
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index c71d4d3..f28a361 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,6 +95,11 @@
   /// zero, we stop writing any new exception contexts in this process.
   static int allowedNumberOfContextsToWrite = 10;
 
+  /// Whether summary2 should be used to resynthesize elements.
+  @Deprecated('Clients should assume summary2 is used.  '
+      'Summary1 support has been removed.')
+  static bool get useSummary2 => true;
+
   /// The scheduler that schedules analysis work in this, and possibly other
   /// analysis drivers.
   final AnalysisDriverScheduler _scheduler;
@@ -1592,7 +1597,7 @@
   }
 
   void _reportException(String path, exception, StackTrace stackTrace) {
-    String contextKey = null;
+    String contextKey;
     if (exception is _ExceptionState) {
       var state = exception as _ExceptionState;
       exception = state.exception;
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 06b9e65..d4c2171 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -27,7 +27,7 @@
 List<bool> _buildExperimentalFlagsArray() => <bool>[
       true, // constant-update-2018
       true, // control-flow-collections
-      IsEnabledByDefault.extension_methods,
+      true, // extension-methods
       IsEnabledByDefault.non_nullable,
       true, // set-literals
       true, // spread-collections
@@ -95,7 +95,8 @@
       EnableString.extension_methods,
       IsEnabledByDefault.extension_methods,
       IsExpired.extension_methods,
-      'Extension Methods');
+      'Extension Methods',
+      firstSupportedVersion: '2.6.0');
 
   static const non_nullable = const ExperimentalFeature(
       3,
@@ -160,7 +161,7 @@
   static const bool control_flow_collections = true;
 
   /// Default state of the experiment "extension-methods"
-  static const bool extension_methods = false;
+  static const bool extension_methods = true;
 
   /// Default state of the experiment "non-nullable"
   static const bool non_nullable = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 80d34b3..cfb2a93 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -507,7 +507,7 @@
 
     ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
 
-    LibraryIdentifier libraryNameNode = null;
+    LibraryIdentifier libraryNameNode;
     var seenPartSources = new Set<Source>();
     var directivesToResolve = <Directive>[];
     int partIndex = 0;
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index d38a651..dc4cc41 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -876,7 +876,7 @@
     }
     // Create locations for every usage of the element.
     List<SearchResult> results = <SearchResult>[];
-    CompilationUnitElement enclosingUnitElement = null;
+    CompilationUnitElement enclosingUnitElement;
     for (;
         i < index.usedElements.length && index.usedElements[i] == elementId;
         i++) {
@@ -956,7 +956,7 @@
 
     // Create results for every usage of the name.
     List<SearchResult> results = <SearchResult>[];
-    CompilationUnitElement enclosingUnitElement = null;
+    CompilationUnitElement enclosingUnitElement;
     for (; i < index.usedNames.length && index.usedNames[i] == nameId; i++) {
       IndexRelationKind relationKind = index.usedNameKinds[i];
       SearchResultKind resultKind = relationToResultKind[relationKind];
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 9dd4e72..4e5e5ac 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -716,7 +716,7 @@
   /// representing the parameter to which the value of the right operand will be
   /// bound. Otherwise, return `null`.
   ParameterElement get _staticParameterElementForRightHandSide {
-    ExecutableElement executableElement = null;
+    ExecutableElement executableElement;
     if (staticElement != null) {
       executableElement = staticElement;
     } else {
@@ -5938,7 +5938,7 @@
   /// If this expression is both in a getter and setter context, the
   /// [AuxiliaryElements] will be set to hold onto the static element from the
   /// getter context.
-  AuxiliaryElements auxiliaryElements = null;
+  AuxiliaryElements auxiliaryElements;
 
   /// Initialize a newly created index expression.
   IndexExpressionImpl.forCascade(
@@ -8921,7 +8921,7 @@
   /// If this expression is both in a getter and setter context, the
   /// [AuxiliaryElements] will be set to hold onto the static element from the
   /// getter context.
-  AuxiliaryElements auxiliaryElements = null;
+  AuxiliaryElements auxiliaryElements;
 
   @override
   List<DartType> tearOffTypeArgumentTypes;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 6efad5a..67c908d 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -6189,7 +6189,7 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    String groupEnd = null;
+    String groupEnd;
     _writer.print('(');
     NodeList<FormalParameter> parameters = node.parameters;
     int size = parameters.length;
@@ -7496,7 +7496,7 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    String groupEnd = null;
+    String groupEnd;
     sink.write('(');
     NodeList<FormalParameter> parameters = node.parameters;
     int size = parameters.length;
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 9f37e6b..0d81332 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -231,7 +231,7 @@
     // type.
     NodeList<SwitchMember> switchMembers = node.members;
     bool foundError = false;
-    DartType firstType = null;
+    DartType firstType;
     for (SwitchMember switchMember in switchMembers) {
       if (switchMember is SwitchCase) {
         Expression expression = switchMember.expression;
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 0f2f144..42f7ab6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -585,8 +585,8 @@
       while (baseParameter is ParameterMember) {
         baseParameter = (baseParameter as ParameterMember).baseElement;
       }
-      DartObjectImpl argumentValue = null;
-      AstNode errorTarget = null;
+      DartObjectImpl argumentValue;
+      AstNode errorTarget;
       if (baseParameter.isNamed) {
         argumentValue = namedValues[baseParameter.name];
         errorTarget = namedNodes[baseParameter.name];
@@ -652,8 +652,8 @@
     ConstantVisitor initializerVisitor = new ConstantVisitor(
         this, externalErrorReporter,
         lexicalEnvironment: parameterMap);
-    String superName = null;
-    NodeList<Expression> superArguments = null;
+    String superName;
+    NodeList<Expression> superArguments;
     for (var i = 0; i < initializers.length; i++) {
       var initializer = initializers[i];
       if (initializer is ConstructorFieldInitializer) {
@@ -875,11 +875,7 @@
       // fixed.
       return true;
     }
-    // TODO(scheglov ) Switch to using this, but not now, dartbug.com/33441
-    if (typeSystem.isSubtypeOf(objType, type)) {
-      return true;
-    }
-    return objType.isSubtypeOf(type);
+    return typeSystem.isSubtypeOf(objType, type);
   }
 
   /// Determine whether the given string is a valid name for a public symbol
@@ -1018,7 +1014,7 @@
 
   @override
   DartObjectImpl visitAdjacentStrings(AdjacentStrings node) {
-    DartObjectImpl result = null;
+    DartObjectImpl result;
     for (StringLiteral string in node.strings) {
       if (result == null) {
         result = string.accept(this);
@@ -1432,7 +1428,7 @@
 
   @override
   DartObjectImpl visitStringInterpolation(StringInterpolation node) {
-    DartObjectImpl result = null;
+    DartObjectImpl result;
     bool first = true;
     for (InterpolationElement element in node.elements) {
       if (first) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 98921f2..c87f158 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1272,7 +1272,7 @@
   /// application classes which have been visited on the way to reaching this
   /// one (this is used to detect circularities).
   List<ConstructorElement> _computeMixinAppConstructors(
-      [List<ClassElementImpl> visitedClasses = null]) {
+      [List<ClassElementImpl> visitedClasses]) {
     // First get the list of constructors of the superclass which need to be
     // forwarded to this class.
     Iterable<ConstructorElement> constructorsToForward;
@@ -1654,7 +1654,7 @@
   /// A table mapping the offset of a directive to the annotations associated
   /// with that directive, or `null` if none of the annotations in the
   /// compilation unit have annotations.
-  Map<int, List<ElementAnnotation>> annotationMap = null;
+  Map<int, List<ElementAnnotation>> annotationMap;
 
   /// A list containing all of the top-level accessors (getters and setters)
   /// contained in this compilation unit.
@@ -4766,7 +4766,7 @@
         buffer.write('>');
       }
       buffer.write('(');
-      String closing = null;
+      String closing;
       ParameterKind kind = ParameterKind.REQUIRED;
       int parameterCount = parameters.length;
       for (int i = 0; i < parameterCount; i++) {
@@ -6965,7 +6965,7 @@
   /// if not present.  If _libraryCycle is set, then the _libraryCycle field
   /// for all libraries reachable from this library in the import/export graph
   /// is also set.
-  List<LibraryElement> _libraryCycle = null;
+  List<LibraryElement> _libraryCycle;
 
   /// A list containing all of the compilation units that are included in this
   /// library using a `part` directive.
@@ -7434,7 +7434,7 @@
         // Pop the elements, and share the component across all
         // of the elements.
         List<LibraryElement> component = <LibraryElement>[];
-        LibraryElementImpl cur = null;
+        LibraryElementImpl cur;
         do {
           cur = stack.removeLast();
           active.remove(cur);
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
index b27a187..63238fc 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
@@ -344,7 +344,7 @@
   List<Conflict> _findMostSpecificFromNamedCandidates(
       Map<Name, FunctionType> map,
       Map<Name, List<FunctionType>> namedCandidates) {
-    List<Conflict> conflicts = null;
+    List<Conflict> conflicts;
 
     for (var name in namedCandidates.keys) {
       if (map.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index 1c9a60d..f457b8a 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -340,7 +340,7 @@
   List<Conflict> _findMostSpecificFromNamedCandidates(
       Map<Name, ExecutableElement> map,
       Map<Name, List<ExecutableElement>> namedCandidates) {
-    List<Conflict> conflicts = null;
+    List<Conflict> conflicts;
 
     for (var name in namedCandidates.keys) {
       if (map.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 6d27b90..737047d 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -608,7 +608,7 @@
       buffer.write('>');
     }
     buffer.write('(');
-    String closing = null;
+    String closing;
     ParameterKind kind = ParameterKind.REQUIRED;
     int parameterCount = parameters.length;
     for (int i = 0; i < parameterCount; i++) {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 68a0c7c..c1339c9 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1259,7 +1259,7 @@
   /**
    * The version of [element] for which members are cached.
    */
-  int _versionOfCachedMembers = null;
+  int _versionOfCachedMembers;
 
   /**
    * Cached [ConstructorElement]s - members or raw elements.
@@ -2847,8 +2847,6 @@
  * A concrete implementation of a [TypeParameterType].
  */
 class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
-  static bool _comparingBounds = false;
-
   @override
   final NullabilitySuffix nullabilitySuffix;
 
@@ -2874,20 +2872,10 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TypeParameterTypeImpl && element == other.element) {
-      if (_comparingBounds) {
-        // If we're comparing bounds already, then we only need type variable
-        // equality.
-        return true;
-      }
-      _comparingBounds = true;
-      try {
-        return bound == other.bound;
-      } finally {
-        _comparingBounds = false;
-      }
+    if (identical(other, this)) {
+      return true;
     }
-    return false;
+    return other is TypeParameterTypeImpl && other.element == element;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index cf5639a..756feb8 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -4,13 +4,9 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -20,7 +16,6 @@
 /// A visitor that will re-write an AST to support the optional `new` and
 /// `const` feature.
 class AstRewriteVisitor extends ScopedVisitor {
-  final bool addConstKeyword;
   final TypeSystem typeSystem;
 
   /// Initialize a newly created visitor.
@@ -30,8 +25,7 @@
       Source source,
       TypeProvider typeProvider,
       AnalysisErrorListener errorListener,
-      {Scope nameScope,
-      this.addConstKeyword: false})
+      {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope);
 
@@ -60,7 +54,7 @@
             astFactory.constructorName(typeName, null, null);
         InstanceCreationExpression instanceCreationExpression =
             astFactory.instanceCreationExpression(
-                _getKeyword(node), constructorName, node.argumentList);
+                null, constructorName, node.argumentList);
         NodeReplacer.replace(node, instanceCreationExpression);
       } else if (element is ExtensionElement) {
         ExtensionOverride extensionOverride = astFactory.extensionOverride(
@@ -94,7 +88,7 @@
           // TODO(scheglov) I think we should drop "typeArguments" below.
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  _getKeyword(node), constructorName, node.argumentList,
+                  null, constructorName, node.argumentList,
                   typeArguments: typeArguments);
           NodeReplacer.replace(node, instanceCreationExpression);
         }
@@ -113,7 +107,7 @@
               astFactory.constructorName(typeName, null, null);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  _getKeyword(node), constructorName, node.argumentList);
+                  null, constructorName, node.argumentList);
           NodeReplacer.replace(node, instanceCreationExpression);
         } else if (prefixedElement is ExtensionElement) {
           PrefixedIdentifier extensionName =
@@ -147,49 +141,11 @@
                 astFactory.constructorName(typeName, node.operator, methodName);
             InstanceCreationExpression instanceCreationExpression =
                 astFactory.instanceCreationExpression(
-                    _getKeyword(node), constructorName, node.argumentList);
+                    null, constructorName, node.argumentList);
             NodeReplacer.replace(node, instanceCreationExpression);
           }
         }
       }
     }
   }
-
-  /// Return the token that should be used in the [InstanceCreationExpression]
-  /// that corresponds to the given invocation [node].
-  Token _getKeyword(MethodInvocation node) {
-    return addConstKeyword
-        ? new KeywordToken(Keyword.CONST, node.offset)
-        : null;
-  }
-
-  /// Return the type of the given class [element] after substituting any type
-  /// arguments from the list of [typeArguments] for the class' type parameters.
-  static InterfaceType getType(TypeSystem typeSystem, ClassElement element,
-      TypeArgumentList typeArguments) {
-    DartType type = element.type;
-
-    List<TypeParameterElement> typeParameters = element.typeParameters;
-    if (typeParameters.isEmpty) {
-      return type;
-    }
-
-    if (typeArguments == null) {
-      return typeSystem.instantiateToBounds(type);
-    }
-
-    List<DartType> argumentTypes;
-    if (typeArguments.arguments.length == typeParameters.length) {
-      argumentTypes = typeArguments.arguments
-          .map((TypeAnnotation argument) => argument.type)
-          .toList();
-    } else {
-      argumentTypes = List<DartType>.filled(
-          typeParameters.length, DynamicTypeImpl.instance);
-    }
-    List<DartType> parameterTypes = typeParameters
-        .map((TypeParameterElement parameter) => parameter.type)
-        .toList();
-    return type.substitute2(argumentTypes, parameterTypes);
-  }
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 4ac8a57..56e6382 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -311,7 +311,7 @@
       ClassElement classElement, SimpleIdentifier propertyName) {
     // TODO(scheglov) Replace with class hierarchy.
     String name = propertyName.name;
-    Element element = null;
+    Element element;
     if (propertyName.inSetterContext()) {
       element = classElement.getSetter(name);
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index ef8de3a..9304c38 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -1035,7 +1035,7 @@
    * A table mapping names that are defined in this scope to the element
    * representing the thing declared with that name.
    */
-  Map<String, Element> _definedNames = null;
+  Map<String, Element> _definedNames;
 
   /**
    * Return the scope in which this scope is lexically enclosed.
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 6bf0d08..b3432d7 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -616,8 +616,8 @@
    */
   LibraryMap initialLibraryMap(bool useDart2jsPaths) {
     List<String> searchedPaths = <String>[];
-    var lastStackTrace = null;
-    var lastException = null;
+    StackTrace lastStackTrace;
+    Object lastException;
     for (File librariesFile in _libraryMapLocations) {
       try {
         String contents = librariesFile.readAsStringSync();
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 8ece3f2..ac9b421 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -189,7 +189,7 @@
     _checkForMismatchedAccessorTypes(interface);
 
     if (!classElement.isAbstract) {
-      List<ExecutableElement> inheritedAbstract = null;
+      List<ExecutableElement> inheritedAbstract;
 
       for (var name in interface.map.keys) {
         if (!name.isAccessibleFor(libraryUri)) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index df889e0..5b76714 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1747,6 +1747,15 @@
     // extensions. They are invalid and the parser has already reported an
     // error at this point. In the future, we should include them in order
     // to get navigation, search, etc.
+    pop(); // body
+    pop(); // initializers
+    pop(); // separator
+    pop(); // parameters
+    pop(); // typeParameters
+    pop(); // name
+    pop(); // returnType
+    pop(); // modifiers
+    pop(); // metadata
   }
 
   @override
@@ -3593,7 +3602,7 @@
 
   /// Return the token that is lexically first.
   Token get beginToken {
-    Token firstToken = null;
+    Token firstToken;
     for (Token token in [
       abstractKeyword,
       externalKeyword,
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index a8dfa2e..2813216 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -774,6 +774,6 @@
   /// and [cause].
   _ElementMismatchException(
       CompilationUnitElement compilationUnit, Element element,
-      [CaughtException cause = null])
+      [CaughtException cause])
       : super('Element mismatch in $compilationUnit at $element', cause);
 }
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index fd7e626..17b73d5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -19,9 +19,7 @@
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
 import 'package:analyzer/src/dart/resolver/resolution_result.dart';
@@ -711,7 +709,7 @@
               [memberName, element.name]);
         }
         if (propertyName.inGetterContext()) {
-          PropertyAccessorElement getter = result.getter;
+          ExecutableElement getter = result.getter;
           if (getter == null) {
             _resolver.errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -1101,6 +1099,16 @@
     return _resolveTypeParameter(type);
   }
 
+  InterfaceType _instantiateAnnotationClass(ClassElement element) {
+    return element.instantiate(
+      typeArguments: List.filled(
+        element.typeParameters.length,
+        _dynamicType,
+      ),
+      nullabilitySuffix: _resolver.noneOrStarSuffix,
+    );
+  }
+
   /**
    * Check for a generic method & apply type arguments if any were passed.
    */
@@ -1254,44 +1262,6 @@
     _resolver.errorReporter.reportErrorForToken(errorCode, token, arguments);
   }
 
-  /// Resolve the [constructorName] to the constructor in the class [element].
-  /// Perform inference using [argumentList].
-  ConstructorElement _resolveAnnotationConstructor(
-    ClassElement element,
-    String constructorName,
-    ArgumentList argumentList,
-  ) {
-    var constructor = constructorName != null
-        ? element.getNamedConstructor(constructorName)
-        : element.unnamedConstructor;
-    if (constructor == null) {
-      return null;
-    }
-    if (!constructor.isAccessibleIn(_definingLibrary)) {
-      return null;
-    }
-
-    var typeParameters = element.typeParameters;
-    if (typeParameters.isEmpty) {
-      return constructor;
-    }
-
-    var typeArgs = _resolver.typeSystem.inferGenericFunctionOrType(
-      typeParameters: typeParameters,
-      parameters: constructor.parameters,
-      declaredReturnType: null,
-      argumentTypes: argumentList.arguments.map((a) => a.staticType).toList(),
-      contextReturnType: null,
-      isConst: true,
-      errorReporter: _resolver.errorReporter,
-      errorNode: argumentList,
-    );
-    return ExecutableMember.from2(
-      constructor,
-      Substitution.fromPairs(typeParameters, typeArgs),
-    );
-  }
-
   void _resolveAnnotationConstructorInvocationArguments(
       Annotation annotation, ConstructorElement constructor) {
     ArgumentList argumentList = annotation.arguments;
@@ -1338,11 +1308,8 @@
       }
       // Class(args)
       if (element1 is ClassElement) {
-        constructor = _resolveAnnotationConstructor(
-          element1,
-          null,
-          annotation.arguments,
-        );
+        constructor = _instantiateAnnotationClass(element1)
+            .lookUpConstructor(null, _definingLibrary);
       } else if (element1 == null) {
         undefined = true;
       }
@@ -1370,11 +1337,8 @@
       }
       // Class.constructor(args)
       if (element1 is ClassElement) {
-        constructor = _resolveAnnotationConstructor(
-          element1,
-          nameNode2.name,
-          annotation.arguments,
-        );
+        constructor = _instantiateAnnotationClass(element1)
+            .lookUpConstructor(nameNode2.name, _definingLibrary);
         nameNode2.staticElement = constructor;
       }
       if (element1 == null && element2 == null) {
@@ -1399,11 +1363,8 @@
           return;
         }
         // prefix.Class.constructor(args)
-        constructor = _resolveAnnotationConstructor(
-          element2,
-          name3,
-          annotation.arguments,
-        );
+        constructor = _instantiateAnnotationClass(element2)
+            .lookUpConstructor(name3, _definingLibrary);
         nameNode3.staticElement = constructor;
       } else if (element2 == null) {
         undefined = true;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 53038fc..b28a0af 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -279,7 +279,7 @@
    * The elements that will be defined later in the current scope, but right
    * now are not declared.
    */
-  HiddenElements _hiddenElements = null;
+  HiddenElements _hiddenElements;
 
   /**
    * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]
@@ -2058,7 +2058,7 @@
    */
   void _checkForAssignmentToFinal(Expression expression) {
     // prepare element
-    Element element = null;
+    Element element;
     AstNode highlightedNode = expression;
     if (expression is Identifier) {
       element = expression.staticElement;
@@ -3650,7 +3650,7 @@
     ExecutableElement accessorElement =
         accessorDeclaration.declaredElement as ExecutableElement;
     if (accessorElement is PropertyAccessorElement) {
-      PropertyAccessorElement counterpartAccessor = null;
+      PropertyAccessorElement counterpartAccessor;
       if (accessorElement.isGetter) {
         counterpartAccessor = accessorElement.correspondingSetter;
       } else {
@@ -3667,8 +3667,8 @@
         return;
       }
       // Default of null == no accessor or no type (dynamic)
-      DartType getterType = null;
-      DartType setterType = null;
+      DartType getterType;
+      DartType setterType;
       // Get an existing counterpart accessor if any.
       if (accessorElement.isGetter) {
         getterType = _getGetterType(accessorElement);
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8e6d623..58b6393 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -560,13 +560,13 @@
   Annotation parseAnnotation() {
     Token atSign = getAndAdvance();
     Identifier name = parsePrefixedIdentifier();
-    Token period = null;
-    SimpleIdentifier constructorName = null;
+    Token period;
+    SimpleIdentifier constructorName;
     if (_matches(TokenType.PERIOD)) {
       period = getAndAdvance();
       constructorName = parseSimpleIdentifier();
     }
-    ArgumentList arguments = null;
+    ArgumentList arguments;
     if (_matches(TokenType.OPEN_PAREN)) {
       arguments = parseArgumentList();
     }
@@ -690,7 +690,7 @@
     if (_matches(TokenType.COMMA)) {
       comma = getAndAdvance();
       if (_matches(TokenType.CLOSE_PAREN)) {
-        comma = null;
+        comma;
       } else {
         message = parseExpression2();
         if (_matches(TokenType.COMMA)) {
@@ -939,7 +939,7 @@
   ///         'break' identifier? ';'
   Statement parseBreakStatement() {
     Token breakKeyword = getAndAdvance();
-    SimpleIdentifier label = null;
+    SimpleIdentifier label;
     if (_matchesIdentifier()) {
       label = _parseSimpleIdentifierUnchecked();
     }
@@ -968,8 +968,8 @@
   ///         assignmentOperator expressionWithoutCascade
   Expression parseCascadeSection() {
     Token period = getAndAdvance();
-    Expression expression = null;
-    SimpleIdentifier functionName = null;
+    Expression expression;
+    SimpleIdentifier functionName;
     if (_matchesIdentifier()) {
       functionName = _parseSimpleIdentifierUnchecked();
     } else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) {
@@ -981,7 +981,7 @@
         Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET);
         expression = astFactory.indexExpressionForCascade(
             period, leftBracket, index, rightBracket);
-        period = null;
+        period;
       } finally {
         _inInitializer = wasInInitializer;
       }
@@ -998,8 +998,8 @@
         if (functionName != null) {
           expression = astFactory.methodInvocation(expression, period,
               functionName, typeArguments, parseArgumentList());
-          period = null;
-          functionName = null;
+          period;
+          functionName;
         } else if (expression == null) {
           // It should not be possible to get here.
           expression = astFactory.methodInvocation(expression, period,
@@ -1011,7 +1011,7 @@
       } while (_isLikelyArgumentList());
     } else if (functionName != null) {
       expression = astFactory.propertyAccess(expression, period, functionName);
-      period = null;
+      period;
     }
     assert(expression != null);
     bool progress = true;
@@ -1065,7 +1065,7 @@
     Token keyword = getAndAdvance();
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
     String className = name.name;
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     TokenType type = _currentToken.type;
     if (type == TokenType.LT) {
       typeParameters = parseTypeParameterList();
@@ -1084,9 +1084,9 @@
     // generate errors if they are not in the order required by the
     // specification.
     //
-    ExtendsClause extendsClause = null;
-    WithClause withClause = null;
-    ImplementsClause implementsClause = null;
+    ExtendsClause extendsClause;
+    WithClause withClause;
+    ImplementsClause implementsClause;
     bool foundClause = true;
     while (foundClause) {
       Keyword keyword = _currentToken.keyword;
@@ -1136,7 +1136,7 @@
     //
     // Look for and skip over the extra-lingual 'native' specification.
     //
-    NativeClause nativeClause = null;
+    NativeClause nativeClause;
     if (_matchesKeyword(Keyword.NATIVE) &&
         _tokenMatches(_peek(), TokenType.STRING)) {
       nativeClause = _parseNativeClause();
@@ -1144,9 +1144,9 @@
     //
     // Parse the body of the class.
     //
-    Token leftBracket = null;
-    List<ClassMember> members = null;
-    Token rightBracket = null;
+    Token leftBracket;
+    List<ClassMember> members;
+    Token rightBracket;
     if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       leftBracket = getAndAdvance();
       members = _parseClassMembers(className, _getEndToken(leftBracket));
@@ -1367,9 +1367,9 @@
           parseSimpleIdentifier(allowKeyword: true, isDeclaration: true),
           parseFormalParameterList());
     } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
-      TypeName returnType = null;
+      TypeName returnType;
       SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true);
-      TypeParameterList typeParameters = null;
+      TypeParameterList typeParameters;
       FormalParameterList parameters = parseFormalParameterList();
       if (_matches(TokenType.COLON) ||
           modifiers.factoryKeyword != null ||
@@ -1484,7 +1484,7 @@
     } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
       SimpleIdentifier methodName =
           _parseSimpleIdentifierUnchecked(isDeclaration: true);
-      TypeParameterList typeParameters = null;
+      TypeParameterList typeParameters;
       FormalParameterList parameters = parseFormalParameterList();
       if (methodName.name == className) {
         _reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type);
@@ -1551,7 +1551,7 @@
   ///         'show' identifier (',' identifier)*
   ///       | 'hide' identifier (',' identifier)*
   List<Combinator> parseCombinators() {
-    List<Combinator> combinators = null;
+    List<Combinator> combinators;
     while (true) {
       Combinator combinator = parseCombinator();
       if (combinator == null) {
@@ -1575,7 +1575,7 @@
     // TODO(brianwilkerson) Consider making the creation of documentation
     // comments be lazy.
     List<DocumentationCommentToken> tokens = parseDocumentationCommentTokens();
-    List<Annotation> metadata = null;
+    List<Annotation> metadata;
     while (_matches(TokenType.AT)) {
       metadata ??= <Annotation>[];
       metadata.add(parseAnnotation());
@@ -1617,7 +1617,7 @@
         return astFactory.commentReference(
             null, astFactory.simpleIdentifier(syntheticToken));
       }
-      Token newKeyword = null;
+      Token newKeyword;
       if (_tokenMatchesKeyword(firstToken, Keyword.NEW)) {
         newKeyword = firstToken;
         firstToken = firstToken.next;
@@ -1715,7 +1715,7 @@
       // Skip GitHub code blocks.
       // https://help.github.com/articles/creating-and-highlighting-code-blocks/
       if (tokens.length != 1) {
-        if (comment.indexOf('```') != -1) {
+        if (comment.contains('```')) {
           isInGitHubCodeBlock = !isInGitHubCodeBlock;
         }
         if (isInGitHubCodeBlock) {
@@ -1800,7 +1800,7 @@
   ///       | topLevelDeclaration
   CompilationUnit parseCompilationUnit2() {
     Token firstToken = _currentToken;
-    ScriptTag scriptTag = null;
+    ScriptTag scriptTag;
     if (_matches(TokenType.SCRIPT_TAG)) {
       scriptTag = astFactory.scriptTag(getAndAdvance());
     }
@@ -2081,7 +2081,7 @@
       return parseFunctionDeclaration(
           commentAndMetadata, modifiers.externalKeyword, null);
     } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
-      TypeName returnType = null;
+      TypeName returnType;
       _validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(
           commentAndMetadata, modifiers.externalKeyword, returnType);
@@ -2196,8 +2196,8 @@
     Token ifKeyword = getAndAdvance();
     Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
     DottedName name = parseDottedName();
-    Token equalToken = null;
-    StringLiteral value = null;
+    Token equalToken;
+    StringLiteral value;
     if (_matches(TokenType.EQ_EQ)) {
       equalToken = getAndAdvance();
       value = parseStringLiteral();
@@ -2241,14 +2241,14 @@
   ///     fieldInitializer:
   ///         ('this' '.')? identifier '=' conditionalExpression cascadeSection*
   ConstructorFieldInitializer parseConstructorFieldInitializer(bool hasThis) {
-    Token keywordToken = null;
-    Token period = null;
+    Token keywordToken;
+    Token period;
     if (hasThis) {
       keywordToken = getAndAdvance();
       period = _expect(TokenType.PERIOD);
     }
     SimpleIdentifier fieldName = parseSimpleIdentifier();
-    Token equals = null;
+    Token equals;
     TokenType type = _currentToken.type;
     if (type == TokenType.EQ) {
       equals = getAndAdvance();
@@ -2298,8 +2298,8 @@
   ///         type ('.' identifier)?
   ConstructorName parseConstructorName() {
     TypeName type = parseTypeName(false);
-    Token period = null;
-    SimpleIdentifier name = null;
+    Token period;
+    SimpleIdentifier name;
     if (_matches(TokenType.PERIOD)) {
       period = getAndAdvance();
       name = parseSimpleIdentifier();
@@ -2319,7 +2319,7 @@
       _reportErrorForToken(
           ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword);
     }
-    SimpleIdentifier label = null;
+    SimpleIdentifier label;
     if (_matchesIdentifier()) {
       label = _parseSimpleIdentifierUnchecked();
     }
@@ -2373,7 +2373,7 @@
   ///         scriptTag? directive*
   CompilationUnit parseDirectives2() {
     Token firstToken = _currentToken;
-    ScriptTag scriptTag = null;
+    ScriptTag scriptTag;
     if (_matches(TokenType.SCRIPT_TAG)) {
       scriptTag = astFactory.scriptTag(getAndAdvance());
     }
@@ -2510,9 +2510,9 @@
   EnumDeclaration parseEnumDeclaration(CommentAndMetadata commentAndMetadata) {
     Token keyword = getAndAdvance();
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
-    Token leftBracket = null;
+    Token leftBracket;
     List<EnumConstantDeclaration> constants = <EnumConstantDeclaration>[];
-    Token rightBracket = null;
+    Token rightBracket;
     if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       leftBracket = getAndAdvance();
       if (_matchesIdentifier() || _matches(TokenType.AT)) {
@@ -2720,8 +2720,8 @@
   ///       | type
   FinalConstVarOrType parseFinalConstVarOrType(bool optional,
       {bool inFunctionType: false}) {
-    Token keywordToken = null;
-    TypeAnnotation type = null;
+    Token keywordToken;
+    TypeAnnotation type;
     Keyword keyword = _currentToken.keyword;
     if (keyword == Keyword.FINAL || keyword == Keyword.CONST) {
       keywordToken = getAndAdvance();
@@ -2755,7 +2755,7 @@
     } else {
       // Support parameters such as `(/*=K*/ key, /*=V*/ value)`
       // This is not supported if the type is required.
-      type = null;
+      type;
     }
     return new FinalConstVarOrType(keywordToken, type);
   }
@@ -2883,14 +2883,14 @@
     bool wasInLoop = _inLoop;
     _inLoop = true;
     try {
-      Token awaitKeyword = null;
+      Token awaitKeyword;
       if (_matchesKeyword(Keyword.AWAIT)) {
         awaitKeyword = getAndAdvance();
       }
       Token forKeyword = _expectKeyword(Keyword.FOR);
       Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
-      VariableDeclarationList variableList = null;
-      Expression initialization = null;
+      VariableDeclarationList variableList;
+      Expression initialization;
       if (!_matches(TokenType.SEMICOLON)) {
         CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
         if (_matchesIdentifier() &&
@@ -2915,8 +2915,8 @@
           if (type == TokenType.COLON) {
             _reportErrorForCurrentToken(ParserErrorCode.COLON_IN_PLACE_OF_IN);
           }
-          DeclaredIdentifier loopVariable = null;
-          SimpleIdentifier identifier = null;
+          DeclaredIdentifier loopVariable;
+          SimpleIdentifier identifier;
           if (variableList == null) {
             // We found: <expression> 'in'
             _reportErrorForCurrentToken(
@@ -2981,12 +2981,12 @@
             ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword);
       }
       Token leftSeparator = _expect(TokenType.SEMICOLON);
-      Expression condition = null;
+      Expression condition;
       if (!_matches(TokenType.SEMICOLON)) {
         condition = parseExpression2();
       }
       Token rightSeparator = _expect(TokenType.SEMICOLON);
-      List<Expression> updaters = null;
+      List<Expression> updaters;
       if (!_matches(TokenType.CLOSE_PAREN)) {
         updaters = parseExpressionList();
       }
@@ -3051,8 +3051,8 @@
         }
         return astFactory.emptyFunctionBody(getAndAdvance());
       }
-      Token keyword = null;
-      Token star = null;
+      Token keyword;
+      Token star;
       bool foundAsync = false;
       bool foundSync = false;
       if (type.isKeyword) {
@@ -3080,7 +3080,7 @@
         if (keyword != null) {
           if (!foundAsync) {
             _reportErrorForToken(ParserErrorCode.INVALID_SYNC, keyword);
-            keyword = null;
+            keyword;
           } else if (star != null) {
             _reportErrorForToken(
                 ParserErrorCode.INVALID_STAR_AFTER_ASYNC, star);
@@ -3093,7 +3093,7 @@
           _advance();
         }
         Expression expression = parseExpression2();
-        Token semicolon = null;
+        Token semicolon;
         if (!inExpression) {
           semicolon = _expect(TokenType.SEMICOLON);
         }
@@ -3118,7 +3118,7 @@
         return astFactory.blockFunctionBody(keyword, star, parseBlock());
       } else if (_matchesKeyword(Keyword.NATIVE)) {
         Token nativeToken = getAndAdvance();
-        StringLiteral stringLiteral = null;
+        StringLiteral stringLiteral;
         if (_matches(TokenType.STRING)) {
           stringLiteral = _parseStringLiteralUnchecked();
         }
@@ -3153,10 +3153,10 @@
       CommentAndMetadata commentAndMetadata,
       Token externalKeyword,
       TypeAnnotation returnType) {
-    Token keywordToken = null;
+    Token keywordToken;
     bool isGetter = false;
     Keyword keyword = _currentToken.keyword;
-    SimpleIdentifier name = null;
+    SimpleIdentifier name;
     if (keyword == Keyword.GET) {
       keywordToken = getAndAdvance();
       isGetter = true;
@@ -3165,13 +3165,13 @@
     }
     if (keywordToken != null && _matches(TokenType.OPEN_PAREN)) {
       name = astFactory.simpleIdentifier(keywordToken, isDeclaration: true);
-      keywordToken = null;
+      keywordToken;
       isGetter = false;
     } else {
       name = parseSimpleIdentifier(isDeclaration: true);
     }
     TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
-    FormalParameterList parameters = null;
+    FormalParameterList parameters;
     if (!isGetter) {
       if (_matches(TokenType.OPEN_PAREN)) {
         parameters = _parseFormalParameterListUnchecked();
@@ -3261,7 +3261,7 @@
   ///         type identifier
   GenericFunctionType parseGenericFunctionTypeAfterReturnType(
       TypeAnnotation returnType) {
-    Token functionKeyword = null;
+    Token functionKeyword;
     if (_matchesKeyword(Keyword.FUNCTION)) {
       functionKeyword = getAndAdvance();
     } else if (_matchesIdentifier()) {
@@ -3269,7 +3269,7 @@
     } else {
       _reportErrorForCurrentToken(ParserErrorCode.MISSING_FUNCTION_KEYWORD);
     }
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     if (_matches(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
@@ -3288,7 +3288,7 @@
   GenericTypeAlias parseGenericTypeAlias(
       CommentAndMetadata commentAndMetadata, Token keyword) {
     Identifier name = _parseSimpleIdentifierUnchecked(isDeclaration: true);
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     if (_matches(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
@@ -3406,8 +3406,8 @@
     Expression condition = parseExpression2();
     Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
     Statement thenStatement = parseStatement2();
-    Token elseKeyword = null;
-    Statement elseStatement = null;
+    Token elseKeyword;
+    Statement elseStatement;
     if (_matchesKeyword(Keyword.ELSE)) {
       elseKeyword = getAndAdvance();
       elseStatement = parseStatement2();
@@ -3444,9 +3444,9 @@
     Token importKeyword = getAndAdvance();
     StringLiteral libraryUri = _parseUri();
     List<Configuration> configurations = _parseConfigurations();
-    Token deferredToken = null;
-    Token asToken = null;
-    SimpleIdentifier prefix = null;
+    Token deferredToken;
+    Token asToken;
+    SimpleIdentifier prefix;
     if (_matchesKeyword(Keyword.DEFERRED)) {
       deferredToken = getAndAdvance();
     }
@@ -4102,8 +4102,8 @@
     }
     FinalConstVarOrType holder = parseFinalConstVarOrType(!inFunctionType,
         inFunctionType: inFunctionType);
-    Token thisKeyword = null;
-    Token period = null;
+    Token thisKeyword;
+    Token period;
     if (_matchesKeyword(Keyword.THIS)) {
       thisKeyword = getAndAdvance();
       period = _expect(TokenType.PERIOD);
@@ -4339,7 +4339,7 @@
       return parseStringLiteral();
     } else if (type == TokenType.INT) {
       Token token = getAndAdvance();
-      int value = null;
+      int value;
       try {
         value = int.parse(token.lexeme);
       } on FormatException {
@@ -4374,7 +4374,7 @@
       return astFactory.doubleLiteral(token, value);
     } else if (type == TokenType.HEXADECIMAL) {
       Token token = getAndAdvance();
-      int value = null;
+      int value;
       try {
         value = int.parse(token.lexeme);
       } on FormatException {
@@ -4443,8 +4443,8 @@
   RedirectingConstructorInvocation parseRedirectingConstructorInvocation(
       bool hasPeriod) {
     Token keyword = getAndAdvance();
-    Token period = null;
-    SimpleIdentifier constructorName = null;
+    Token period;
+    SimpleIdentifier constructorName;
     if (hasPeriod) {
       period = getAndAdvance();
       if (_matchesIdentifier()) {
@@ -4482,7 +4482,7 @@
           expression, asOperator, parseTypeNotVoid(true));
     } else if (keyword == Keyword.IS) {
       Token isOperator = getAndAdvance();
-      Token notOperator = null;
+      Token notOperator;
       if (_matches(TokenType.BANG)) {
         notOperator = getAndAdvance();
       }
@@ -4614,7 +4614,7 @@
     }
     _treeDepth++;
     try {
-      List<Label> labels = null;
+      List<Label> labels;
       while (
           _matchesIdentifier() && _currentToken.next.type == TokenType.COLON) {
         Label label = parseLabel(isDeclaration: true);
@@ -4664,8 +4664,8 @@
   ///         'super' ('.' identifier)? arguments
   SuperConstructorInvocation parseSuperConstructorInvocation() {
     Token keyword = getAndAdvance();
-    Token period = null;
-    SimpleIdentifier constructorName = null;
+    Token period;
+    SimpleIdentifier constructorName;
     if (_matches(TokenType.PERIOD)) {
       period = getAndAdvance();
       constructorName = parseSimpleIdentifier();
@@ -4695,7 +4695,7 @@
       Expression expression = parseExpression2();
       Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
       Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
-      Token defaultKeyword = null;
+      Token defaultKeyword;
       List<SwitchMember> members = <SwitchMember>[];
       TokenType type = _currentToken.type;
       while (type != TokenType.EOF && type != TokenType.CLOSE_CURLY_BRACKET) {
@@ -4852,20 +4852,20 @@
     Token tryKeyword = getAndAdvance();
     Block body = _parseBlockChecked();
     List<CatchClause> catchClauses = <CatchClause>[];
-    Block finallyClause = null;
+    Block finallyClause;
     while (_matchesKeyword(Keyword.ON) || _matchesKeyword(Keyword.CATCH)) {
-      Token onKeyword = null;
-      TypeName exceptionType = null;
+      Token onKeyword;
+      TypeName exceptionType;
       if (_matchesKeyword(Keyword.ON)) {
         onKeyword = getAndAdvance();
         exceptionType = parseTypeNotVoid(false);
       }
-      Token catchKeyword = null;
-      Token leftParenthesis = null;
-      SimpleIdentifier exceptionParameter = null;
-      Token comma = null;
-      SimpleIdentifier stackTraceParameter = null;
-      Token rightParenthesis = null;
+      Token catchKeyword;
+      Token leftParenthesis;
+      SimpleIdentifier exceptionParameter;
+      Token comma;
+      SimpleIdentifier stackTraceParameter;
+      Token rightParenthesis;
       if (_matchesKeyword(Keyword.CATCH)) {
         catchKeyword = getAndAdvance();
         leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -4888,7 +4888,7 @@
           rightParenthesis,
           catchBody));
     }
-    Token finallyKeyword = null;
+    Token finallyKeyword;
     if (_matchesKeyword(Keyword.FINALLY)) {
       finallyKeyword = getAndAdvance();
       finallyClause = _parseBlockChecked();
@@ -4942,7 +4942,7 @@
   ///         typeWithoutFunction
   ///       | functionType
   TypeAnnotation parseTypeAnnotation(bool inExpression) {
-    TypeAnnotation type = null;
+    TypeAnnotation type;
     if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
       // Generic function type with no return type.
       type = parseGenericFunctionTypeAfterReturnType(null);
@@ -4994,7 +4994,7 @@
   ///         functionType
   ///       | typeNotVoidWithoutFunction
   TypeAnnotation parseTypeNotVoid(bool inExpression) {
-    TypeAnnotation type = null;
+    TypeAnnotation type;
     if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
       // Generic function type with no return type.
       type = parseGenericFunctionTypeAfterReturnType(null);
@@ -5150,8 +5150,8 @@
     // user is in the middle of inserting "int bar;" prior to
     // "@deprecated foo() {}").
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
-    Token equals = null;
-    Expression initializer = null;
+    Token equals;
+    Expression initializer;
     if (_matches(TokenType.EQ)) {
       equals = getAndAdvance();
       initializer = parseExpression2();
@@ -5268,7 +5268,7 @@
   ///         'yield' '*'? expression ';'
   YieldStatement parseYieldStatement() {
     Token yieldToken = getAndAdvance();
-    Token star = null;
+    Token star;
     if (_matches(TokenType.STAR)) {
       star = getAndAdvance();
     }
@@ -5390,7 +5390,7 @@
   ///
   /// This method must be kept in sync with [parseTypeAnnotation].
   Token skipTypeAnnotation(Token startToken) {
-    Token next = null;
+    Token next;
     if (_atGenericFunctionTypeAfterReturnType(startToken)) {
       // Generic function type with no return type.
       next = skipGenericFunctionTypeAfterReturnType(startToken);
@@ -6053,7 +6053,7 @@
     if (_matches(TokenType.COMMA)) {
       comma = getAndAdvance();
       if (_matches(TokenType.CLOSE_PAREN)) {
-        comma = null;
+        comma;
       } else {
         message = parseExpression2();
         if (_matches(TokenType.COMMA)) {
@@ -6142,14 +6142,14 @@
       TypeParameterList typeParameters) {
     Token equals = _expect(TokenType.EQ);
     TypeName superclass = parseTypeName(false);
-    WithClause withClause = null;
+    WithClause withClause;
     if (_matchesKeyword(Keyword.WITH)) {
       withClause = parseWithClause();
     } else {
       _reportErrorForCurrentToken(
           ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.lexeme]);
     }
-    ImplementsClause implementsClause = null;
+    ImplementsClause implementsClause;
     if (_matchesKeyword(Keyword.IMPLEMENTS)) {
       implementsClause = parseImplementsClause();
     }
@@ -6186,7 +6186,7 @@
   /// Parse a list of configurations. Return the configurations that were
   /// parsed, or `null` if there are no configurations.
   List<Configuration> _parseConfigurations() {
-    List<Configuration> configurations = null;
+    List<Configuration> configurations;
     while (_matchesKeyword(Keyword.IF)) {
       configurations ??= <Configuration>[];
       configurations.add(parseConfiguration());
@@ -6204,8 +6204,8 @@
       SimpleIdentifier name,
       FormalParameterList parameters) {
     bool bodyAllowed = externalKeyword == null;
-    Token separator = null;
-    List<ConstructorInitializer> initializers = null;
+    Token separator;
+    List<ConstructorInitializer> initializers;
     if (_matches(TokenType.COLON)) {
       separator = getAndAdvance();
       initializers = <ConstructorInitializer>[];
@@ -6239,7 +6239,7 @@
             ParserErrorCode.FACTORY_WITH_INITIALIZERS, factoryKeyword);
       }
     }
-    ConstructorName redirectedConstructor = null;
+    ConstructorName redirectedConstructor;
     FunctionBody body;
     if (_matches(TokenType.EQ)) {
       separator = getAndAdvance();
@@ -6333,17 +6333,17 @@
     // better.
     //
     List<FormalParameter> parameters = <FormalParameter>[];
-    Token leftSquareBracket = null;
-    Token rightSquareBracket = null;
-    Token leftCurlyBracket = null;
-    Token rightCurlyBracket = null;
+    Token leftSquareBracket;
+    Token rightSquareBracket;
+    Token leftCurlyBracket;
+    Token rightCurlyBracket;
     ParameterKind kind = ParameterKind.REQUIRED;
     bool firstParameter = true;
     bool reportedMultiplePositionalGroups = false;
     bool reportedMultipleNamedGroups = false;
     bool reportedMixedGroups = false;
     bool wasOptionalParameter = false;
-    Token initialToken = null;
+    Token initialToken;
     do {
       if (firstParameter) {
         firstParameter = false;
@@ -6430,7 +6430,7 @@
                 ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
                 ['}', ']']);
             rightCurlyBracket = rightSquareBracket;
-            rightSquareBracket = null;
+            rightSquareBracket;
             // Skip over synthetic closer inserted by fasta
             // since we've already reported an error
             if (_currentToken.type == TokenType.CLOSE_CURLY_BRACKET &&
@@ -6452,7 +6452,7 @@
                 ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
                 [']', '}']);
             rightSquareBracket = rightCurlyBracket;
-            rightCurlyBracket = null;
+            rightCurlyBracket;
             // Skip over synthetic closer inserted by fasta
             // since we've already reported an error
             if (_currentToken.type == TokenType.CLOSE_SQUARE_BRACKET &&
@@ -6535,12 +6535,12 @@
   ///         returnType? name
   FunctionTypeAlias _parseFunctionTypeAlias(
       CommentAndMetadata commentAndMetadata, Token keyword) {
-    TypeAnnotation returnType = null;
+    TypeAnnotation returnType;
     if (hasReturnTypeInTypeAlias) {
       returnType = parseTypeAnnotation(false);
     }
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     if (_matches(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
@@ -6989,7 +6989,7 @@
         }
       } else {
         Token openToken = getAndAdvance();
-        Expression expression = null;
+        Expression expression;
         if (_matchesKeyword(Keyword.THIS)) {
           expression = astFactory.thisExpression(getAndAdvance());
         } else {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 16c150d..1a6ab3f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1864,7 +1864,7 @@
   /// Return `true` if the given [expression] is resolved to a constant
   /// variable.
   bool _isDebugConstant(Expression expression) {
-    Element element = null;
+    Element element;
     if (expression is Identifier) {
       element = expression.staticElement;
     } else if (expression is PropertyAccess) {
@@ -3044,22 +3044,22 @@
 
   /// The class declaration representing the class containing the current node,
   /// or `null` if the current node is not contained in a class.
-  ClassDeclaration _enclosingClassDeclaration = null;
+  ClassDeclaration _enclosingClassDeclaration;
 
   /// The function type alias representing the function type containing the
   /// current node, or `null` if the current node is not contained in a function
   /// type alias.
-  FunctionTypeAlias _enclosingFunctionTypeAlias = null;
+  FunctionTypeAlias _enclosingFunctionTypeAlias;
 
   /// The element representing the function containing the current node, or
   /// `null` if the current node is not contained in a function.
-  ExecutableElement _enclosingFunction = null;
+  ExecutableElement _enclosingFunction;
 
   /// The mixin declaration representing the class containing the current node,
   /// or `null` if the current node is not contained in a mixin.
-  MixinDeclaration _enclosingMixinDeclaration = null;
+  MixinDeclaration _enclosingMixinDeclaration;
 
-  InferenceContext inferenceContext = null;
+  InferenceContext inferenceContext;
 
   /// The object keeping track of which elements have had their types promoted.
   TypePromotionManager _promoteManager;
@@ -3171,7 +3171,7 @@
     }
   }
 
-  NullabilitySuffix get _noneOrStarSuffix {
+  NullabilitySuffix get noneOrStarSuffix {
     return _nonNullableEnabled
         ? NullabilitySuffix.none
         : NullabilitySuffix.star;
@@ -3189,7 +3189,7 @@
   /// @param expression the expression with which the element is associated
   /// @return the element associated with the given expression
   VariableElement getOverridableStaticElement(Expression expression) {
-    Element element = null;
+    Element element;
     if (expression is SimpleIdentifier) {
       element = expression.staticElement;
     } else if (expression is PrefixedIdentifier) {
@@ -3241,7 +3241,7 @@
     // parameter and return type are in terms of the surrounding context.
     return fnType.instantiate(typeParameters.map((TypeParameter t) {
       return t.declaredElement.instantiate(
-        nullabilitySuffix: _noneOrStarSuffix,
+        nullabilitySuffix: noneOrStarSuffix,
       );
     }).toList());
   }
@@ -4312,9 +4312,9 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    node.accept(elementResolver);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
     node.argumentList?.accept(this);
-    node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
 
@@ -4419,9 +4419,9 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    node.accept(elementResolver);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
     node.argumentList?.accept(this);
-    node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
 
@@ -4994,7 +4994,7 @@
     int requiredParameterCount = 0;
     int unnamedParameterCount = 0;
     List<ParameterElement> unnamedParameters = new List<ParameterElement>();
-    Map<String, ParameterElement> namedParameters = null;
+    Map<String, ParameterElement> namedParameters;
     int length = parameters.length;
     for (int i = 0; i < length; i++) {
       ParameterElement parameter = parameters[i];
@@ -5016,7 +5016,7 @@
     List<ParameterElement> resolvedParameters =
         new List<ParameterElement>(argumentCount);
     int positionalArgumentCount = 0;
-    HashSet<String> usedNames = null;
+    HashSet<String> usedNames;
     bool noBlankArguments = true;
     for (int i = 0; i < argumentCount; i++) {
       Expression argument = arguments[i];
@@ -6124,7 +6124,7 @@
       return;
     }
 
-    DartType type = null;
+    DartType type;
     if (element == DynamicElementImpl.instance) {
       _setElement(typeName, element);
       type = DynamicTypeImpl.instance;
@@ -6548,8 +6548,8 @@
   final Source source;
   final AnalysisErrorListener errorListener;
 
-  Scope libraryScope = null;
-  TypeNameResolver typeNameResolver = null;
+  Scope libraryScope;
+  TypeNameResolver typeNameResolver;
 
   TypeParameterBoundsResolver(this.typeSystem, this.library, this.source,
       this.errorListener, FeatureSet featureSet)
@@ -6636,7 +6636,7 @@
   void _resolveTypeParameters(
       TypeParameterList typeParameters, Scope createTypeParametersScope()) {
     if (typeParameters != null) {
-      Scope typeParametersScope = null;
+      Scope typeParametersScope;
       for (TypeParameter typeParameter in typeParameters.typeParameters) {
         TypeAnnotation bound = typeParameter.bound;
         if (bound != null) {
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 67dfd49..f981dcf 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -367,7 +367,7 @@
 
   @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
-    String libraryName = null;
+    String libraryName;
     Expression key = node.key;
     if (key is SimpleStringLiteral) {
       libraryName = "$_LIBRARY_PREFIX${key.value}";
@@ -486,7 +486,7 @@
    * 'lib' directory within the SDK.
    */
   @override
-  String path = null;
+  String path;
 
   /**
    * The name of the category containing the library. Unless otherwise specified
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index e8108bb..5d44d4b 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -107,9 +107,21 @@
    * inferred type parameters found by the resolver.
    */
   void inferConstructorName(ConstructorName node, InterfaceType type) {
+    // TODO(scheglov) Inline.
     node.type.type = type;
-    if (type != _typeSystem.instantiateToBounds(type.element.type)) {
-      _resolver.inferenceContext.recordInference(node.parent, type);
+    // TODO(scheglov) Remove when DDC stops using analyzer.
+    var element = type.element;
+    if (element.typeParameters.isNotEmpty) {
+      var typeParameterBounds = _typeSystem.instantiateTypeFormalsToBounds(
+        element.typeParameters,
+      );
+      var instantiatedToBounds = element.instantiate(
+        typeArguments: typeParameterBounds,
+        nullabilitySuffix: _noneOrStarSuffix,
+      );
+      if (type != instantiatedToBounds) {
+        _resolver.inferenceContext.recordInference(node.parent, type);
+      }
     }
   }
 
@@ -1389,13 +1401,13 @@
       }
       ClassElement returnType = library.getType(elementName);
       if (returnType != null) {
-        if (returnType.typeParameters.isNotEmpty) {
-          // Caller can't deal with unbound type parameters, so substitute
-          // `dynamic`.
-          return returnType.type.instantiate(
-              returnType.typeParameters.map((_) => _dynamicType).toList());
-        }
-        return returnType.type;
+        return returnType.instantiate(
+          typeArguments: List.filled(
+            returnType.typeParameters.length,
+            _dynamicType,
+          ),
+          nullabilitySuffix: _noneOrStarSuffix,
+        );
       }
     }
     return null;
@@ -1802,7 +1814,7 @@
         e.library.source.uri.toString() == 'dart:_foreign_helper' &&
         e.name == 'JS') {
       String typeStr = _getFirstArgumentAsString(node.argumentList);
-      DartType returnType = null;
+      DartType returnType;
       if (typeStr == '-dynamic') {
         returnType = _typeProvider.bottomType;
       } else {
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index f6687b4..810d916 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -1345,7 +1345,7 @@
           TokenFactory.tokenFromKeyword(Keyword.EXTENDS), bound);
 
   static TypeParameterList typeParameterList([List<String> typeNames]) {
-    List<TypeParameter> typeParameters = null;
+    List<TypeParameter> typeParameters;
     if (typeNames != null && typeNames.isNotEmpty) {
       typeParameters = new List<TypeParameter>();
       for (String typeName in typeNames) {
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 7a84adf..d64f2d5 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -361,7 +361,7 @@
     }
 
     List<TypeParameterElement> getFreeParameters(DartType rootType) {
-      List<TypeParameterElement> parameters = null;
+      List<TypeParameterElement> parameters;
       Set<DartType> visitedTypes = new HashSet<DartType>();
 
       void appendParameters(DartType type) {
@@ -1174,7 +1174,7 @@
   }
 
   static List<T> _transformList<T>(List<T> list, T f(T t)) {
-    List<T> newList = null;
+    List<T> newList;
     for (var i = 0; i < list.length; i++) {
       var item = list[i];
       var newItem = f(item);
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 52439ce..8217608 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1266,8 +1266,8 @@
       }
     }
 
-    String docComplete = null;
-    String docSummary = null;
+    String docComplete;
+    String docSummary;
 
     void setDartDoc(AnnotatedNode node) {
       if (node.documentationComment != null) {
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index bb96dd0..ff48204 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -381,8 +381,14 @@
     _indexUnitDeclarations(unitContext, unitRef, unitNode);
   }
 
-  MethodElementImpl _method(ClassElementImpl enclosing, Reference reference) {
-    enclosing.methods;
+  MethodElementImpl _method(ElementImpl enclosing, Reference reference) {
+    if (enclosing is ClassElementImpl) {
+      enclosing.methods;
+    } else if (enclosing is ExtensionElementImpl) {
+      enclosing.methods;
+    } else {
+      throw StateError('${enclosing.runtimeType}');
+    }
     // Requesting methods sets elements for all of them.
     assert(reference.element != null);
     return reference.element;
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index ac7435a..5d77644 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -10,15 +10,18 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/summary2/ast_resolver.dart';
 import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
 
 class MetadataResolver extends ThrowingAstVisitor<void> {
   final Linker _linker;
   final LibraryElement _libraryElement;
   final Scope _libraryScope;
   final CompilationUnitElement _unitElement;
+  Scope _scope;
 
-  MetadataResolver(this._linker, this._libraryElement, this._libraryScope,
-      this._unitElement);
+  MetadataResolver(
+      this._linker, this._libraryElement, this._libraryScope, this._unitElement)
+      : _scope = _libraryScope;
 
   @override
   void visitAnnotation(Annotation node) {
@@ -27,7 +30,7 @@
     var holder = ElementHolder();
     node.accept(LocalElementBuilder(holder, null));
 
-    var astResolver = AstResolver(_linker, _libraryElement, _libraryScope);
+    var astResolver = AstResolver(_linker, _libraryElement, _scope);
     astResolver.rewriteAst(node);
     astResolver.resolve(node);
   }
@@ -36,7 +39,13 @@
   void visitClassDeclaration(ClassDeclaration node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.members.accept(this);
+
+    _scope = LinkingNodeContext.get(node).scope;
+    try {
+      node.members.accept(this);
+    } finally {
+      _scope = _libraryScope;
+    }
   }
 
   @override
@@ -82,7 +91,13 @@
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.members.accept(this);
+
+    _scope = LinkingNodeContext.get(node).scope;
+    try {
+      node.members.accept(this);
+    } finally {
+      _scope = _libraryScope;
+    }
   }
 
   @override
@@ -161,7 +176,13 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.members.accept(this);
+
+    _scope = LinkingNodeContext.get(node).scope;
+    try {
+      node.members.accept(this);
+    } finally {
+      _scope = _libraryScope;
+    }
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 2cef609..76b23f9 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -94,9 +94,9 @@
         variable.initializer.accept(LocalElementBuilder(holder, null));
         (element as VariableElementImpl).encloseElements(holder.functions);
 
-        InferenceContext.setType(variable.initializer, typeNode.type);
         var astResolver = AstResolver(linker, _library, _scope);
         astResolver.rewriteAst(variable.initializer);
+        InferenceContext.setType(variable.initializer, typeNode.type);
         astResolver.resolve(variable.initializer);
       }
     }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3a196922..0c0a8e6 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1012,7 +1012,7 @@
 
     var type = functionType.returnType;
 
-    ClassElement expectedElement = null;
+    ClassElement expectedElement;
     if (body.isAsynchronous) {
       if (body.isGenerator) {
         // Stream<T> -> T
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index d0e19d8..a4707b5 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -147,7 +147,7 @@
    */
   DartType _computeParameterType(ParameterElement parameter, int index,
       List<FunctionType> overriddenTypes) {
-    DartType parameterType = null;
+    DartType parameterType;
     int length = overriddenTypes.length;
     for (int i = 0; i < length; i++) {
       ParameterElement matchingParameter = _getCorrespondingParameter(
@@ -191,7 +191,7 @@
    * want to be smarter about it.
    */
   DartType _computeReturnType(Iterable<DartType> overriddenReturnTypes) {
-    DartType returnType = null;
+    DartType returnType;
     for (DartType type in overriddenReturnTypes) {
       if (type == null) {
         type = typeProvider.dynamicType;
@@ -567,7 +567,7 @@
    * Initialize a newly created gatherer to gather all of the variables that
    * pass the given [filter] (or all variables if no filter is provided).
    */
-  VariableGatherer([this.filter = null]);
+  VariableGatherer([this.filter]);
 
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 7e9a9ed..87a5af6 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -35,6 +35,10 @@
     return _node(search, (n) => n is Block);
   }
 
+  BooleanLiteral booleanLiteral(String search) {
+    return _node(search, (n) => n is BooleanLiteral);
+  }
+
   BreakStatement breakStatement(String search) {
     return _node(search, (n) => n is BreakStatement);
   }
@@ -75,6 +79,10 @@
     return _node(search, (n) => n is DoStatement);
   }
 
+  DoubleLiteral doubleLiteral(String search) {
+    return _node(search, (n) => n is DoubleLiteral);
+  }
+
   ExportDirective export(String search) {
     return _node(search, (n) => n is ExportDirective);
   }
@@ -179,6 +187,10 @@
     return _node(search, (n) => n is NamedExpression);
   }
 
+  NullLiteral nullLiteral(String search) {
+    return _node(search, (n) => n is NullLiteral);
+  }
+
   ParenthesizedExpression parenthesized(String search) {
     return _node(search, (n) => n is ParenthesizedExpression);
   }
@@ -239,6 +251,10 @@
     return _node(search, (n) => n is SwitchStatement);
   }
 
+  SymbolLiteral symbolLiteral(String search) {
+    return _node(search, (n) => n is SymbolLiteral);
+  }
+
   ThisExpression this_(String search) {
     return _node(search, (n) => n is ThisExpression);
   }
@@ -290,7 +306,7 @@
 
   AstNode _node(String search, bool Function(AstNode) predicate) {
     var index = content.indexOf(search);
-    if (content.indexOf(search, index + 1) != -1) {
+    if (content.contains(search, index + 1)) {
       throw new StateError('The pattern |$search| is not unique in:\n$content');
     }
     if (index < 0) {
diff --git a/pkg/analyzer/lib/src/util/glob.dart b/pkg/analyzer/lib/src/util/glob.dart
index 97c122f..0283753 100644
--- a/pkg/analyzer/lib/src/util/glob.dart
+++ b/pkg/analyzer/lib/src/util/glob.dart
@@ -81,8 +81,8 @@
   static bool _hasJustPrefix(String pattern, String prefix) {
     if (pattern.startsWith(prefix)) {
       int prefixLength = prefix.length;
-      return pattern.indexOf('*', prefixLength) == -1 &&
-          pattern.indexOf('?', prefixLength) == -1;
+      return !pattern.contains('*', prefixLength) &&
+          !pattern.contains('?', prefixLength);
     }
     return false;
   }
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index d66c851..5fcbbaf 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -80,7 +80,7 @@
       String fileUriPart = uriPath.substring(slash + 1);
       String filePath = fileUriPart.replaceAll('/', _context.separator);
 
-      if (packageName.indexOf('.') == -1) {
+      if (!packageName.contains('.')) {
         String fullFilePath = _context.join(_workspace.root, 'third_party',
             'dart', packageName, 'lib', filePath);
         File file = _workspace.findFile(fullFilePath);
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 4a90853..db57bbb 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -165,6 +165,10 @@
 var v = const A(foo);
 ''', [
       error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 116, 3),
+      error(
+          CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+          116,
+          3),
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 6a4c187..8f4902a7 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -588,7 +588,7 @@
 
   test_visitConstructorName_unnamed() async {
     ClassElementImpl classA = ElementFactory.classElement2("A");
-    String constructorName = null;
+    String constructorName;
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
@@ -738,7 +738,7 @@
 
   test_visitInstanceCreationExpression_unnamed() async {
     ClassElementImpl classA = ElementFactory.classElement2("A");
-    String constructorName = null;
+    String constructorName;
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
@@ -754,7 +754,7 @@
 
   test_visitInstanceCreationExpression_unnamed_namedParameter() async {
     ClassElementImpl classA = ElementFactory.classElement2("A");
-    String constructorName = null;
+    String constructorName;
     ConstructorElementImpl constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     String parameterName = "a";
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index fc6c5d50c..d3e8852 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -2,13 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'resolver_test_case.dart';
+import '../src/dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -17,221 +14,203 @@
 }
 
 @reflectiveTest
-class ErrorSuppressionTest extends ResolverTestCase {
+class ErrorSuppressionTest extends DriverResolutionTest {
   String get ignoredCode => 'const_initialized_with_non_constant_value';
 
-  List<ErrorCode> get reportedCodes => [
-        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      ];
-
-  List<ErrorCode> get reportedCodesWithAssignment => [
-        StaticTypeWarningCode.INVALID_ASSIGNMENT,
-        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      ];
-
   test_error_code_mismatch() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore: $ignoredCode
 int x = '';
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 61, 2),
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 75,
+          1),
+    ]);
   }
 
   test_ignore_first() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore: invalid_assignment
 int x = '';
 // ... but no ignore here ...
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+          1),
+    ]);
   }
 
   test_ignore_first_trailing() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = ''; // ignore: invalid_assignment
 // ... but no ignore here ...
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+          1),
+    ]);
   }
 
   test_ignore_for_file() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 // ignore_for_file: invalid_assignment
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+          1),
+    ]);
   }
 
   test_ignore_for_file_whitespace_variant() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 //ignore_for_file:   $ignoredCode , invalid_assignment
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_ignore_only_trailing() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = ''; // ignore: invalid_assignment
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_ignore_second() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 //INVALID_ASSIGNMENT
 int x = '';
 // ignore: $ignoredCode
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+    ]);
   }
 
   test_ignore_second_trailing() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 //INVALID_ASSIGNMENT
 int x = '';
 const y = x; // ignore: $ignoredCode
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+    ]);
   }
 
   test_ignore_upper_case() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = ''; // ignore: INVALID_ASSIGNMENT
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_invalid_error_code() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore: right_format_wrong_code
 int x = '';
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 43, 2),
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 57,
+          1),
+    ]);
   }
 
   test_missing_error_codes() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
     int x = 3;
 // ignore:
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 43,
+          1),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 43, 1),
+    ]);
   }
 
   test_missing_metadata_suffix() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore invalid_assignment
 String y = 3; //INVALID_ASSIGNMENT
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 40, 1),
+    ]);
   }
 
   test_multiple_comments() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = ''; //This is the first comment...
 // ignore: $ignoredCode
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+    ]);
   }
 
   test_multiple_ignore_for_files() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 // ignore_for_file: invalid_assignment,$ignoredCode
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 // ignore: invalid_assignment, $ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_trailing() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 const String y = x; // ignore: invalid_assignment, $ignoredCode
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_whitespace_variant_1() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 //ignore:invalid_assignment,$ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_whitespace_variant_2() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 //ignore: invalid_assignment,$ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_whitespace_variant_3() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 // ignore: invalid_assignment,$ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_no_ignores() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+          1),
+    ]);
   }
 
   test_trailing_not_above() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = ''; // ignore: invalid_assignment
 int y = '';
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.INVALID_ASSIGNMENT,
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 50, 2),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index e97dbde..f5d274f 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -166,6 +166,29 @@
 ''');
   }
 
+  test_fuzz_15() async {
+    // `@A` is not a valid annotation, it is missing arguments.
+    // There was a bug that we did not check for arguments being missing.
+    await _assertCanBeAnalyzed(r'''
+class A<T> {}
+
+@A
+class B {}
+''');
+  }
+
+  test_fuzz_16() async {
+    // The default constructor of `A` does not have formal parameters.
+    // But we give it arguments.
+    // There was a bug that we did not check for this mismatch.
+    await _assertCanBeAnalyzed(r'''
+class A<T> {}
+
+@A(0)
+class B {}
+''');
+  }
+
   test_fuzz_38091() async {
     // https://github.com/dart-lang/sdk/issues/38091
     // this caused an infinite loop in parser recovery
diff --git a/pkg/analyzer/test/generated/issues_test.dart b/pkg/analyzer/test/generated/issues_test.dart
index 93b97b9..198943b 100644
--- a/pkg/analyzer/test/generated/issues_test.dart
+++ b/pkg/analyzer/test/generated/issues_test.dart
@@ -16,6 +16,26 @@
 /// not obvious where to put the test otherwise.
 @reflectiveTest
 class IssuesTest extends DriverResolutionTest {
+  /// https://github.com/dart-lang/sdk/issues/38565
+  ///
+  /// The issue was that type inference for annotation instantiation
+  /// was done incorrectly, without resolving arguments to the annotation
+  /// constructor. So, we were trying to perform type inference using null
+  /// types of arguments.
+  test_issue38565() async {
+    await resolveTestCode('''
+class A<T> {
+  const A(int a);
+}
+
+class C {
+  @A(0)
+  int field;
+}
+''');
+    // Should not crash.
+  }
+
   /// https://github.com/dart-lang/sdk/issues/38589
   test_issue38589() async {
     await resolveTestCode('''
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index b219c94..75f8910 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -3,11 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/dart/resolution/driver_resolution.dart';
-import 'resolver_test_case.dart';
+import 'test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -190,22 +189,24 @@
   }
 }
 
-class PubSuggestionCodeTest extends ResolverTestCase {
+class PubSuggestionCodeTest extends DriverResolutionTest {
   // TODO(brianwilkerson) The tests in this class are not being run, and all but
   //  the first would fail. We should implement these checks and enable the
   //  tests.
   test_import_package() async {
     await assertErrorsInCode('''
 import 'package:somepackage/other.dart';
-''', [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+''', [
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+    ]);
   }
 
   test_import_packageWithDotDot() async {
     await assertErrorsInCode('''
 import 'package:somepackage/../other.dart';
 ''', [
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+      error(HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, 0, 0),
     ]);
   }
 
@@ -213,71 +214,70 @@
     await assertErrorsInCode('''
 import 'package:../other.dart';
 ''', [
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+      error(HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, 0, 0),
     ]);
   }
 
   test_import_referenceIntoLibDirectory() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/lib/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/web/test.dart", "import '../lib/other.dart';", [
+      error(HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, 0, 0),
+    ]);
   }
 
   test_import_referenceIntoLibDirectory_no_pubspec() async {
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/lib/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/web/test.dart", "import '../lib/other.dart';", []);
   }
 
   test_import_referenceOutOfLibDirectory() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/web/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/test.dart", "import '../web/other.dart';", [
+      error(HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, 0, 0),
+    ]);
   }
 
   test_import_referenceOutOfLibDirectory_no_pubspec() async {
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/web/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/test.dart", "import '../web/other.dart';", []);
   }
 
   test_import_valid_inside_lib1() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/lib/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/test.dart", "import 'other.dart';", []);
   }
 
   test_import_valid_inside_lib2() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/bar/other.dart", "");
-    Source source = addNamedSource(
-        "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/lib/bar/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/foo/test.dart", "import '../bar/other.dart';", []);
   }
 
   test_import_valid_outside_lib() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/web/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib2/test.dart", "import '../web/other.dart';", []);
+  }
+
+  Future<void> _assertErrorsInCodeInFile(
+      String path, String content, List<ExpectedError> expectedErrors) async {
+    path = convertPath(path);
+    newFile(path, content: content);
+    result = await resolveFile(path);
+
+    var errorListener = new GatheringErrorListener();
+    errorListener.addAll(result.errors);
+    errorListener.assertErrors(expectedErrors);
   }
 }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index c92e79d..11a75d9 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1681,6 +1681,34 @@
     expect(extension.members, hasLength(0));
   }
 
+  void test_constructor_named() {
+    var unit = parseCompilationUnit('''
+extension E on C {
+  E.named();
+}
+class C {}
+''', errors: [
+      expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
+    ]);
+    expect(unit.declarations, hasLength(2));
+    var extension = unit.declarations[0] as ExtensionDeclaration;
+    expect(extension.members, hasLength(0));
+  }
+
+  void test_constructor_unnamed() {
+    var unit = parseCompilationUnit('''
+extension E on C {
+  E();
+}
+class C {}
+''', errors: [
+      expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
+    ]);
+    expect(unit.declarations, hasLength(2));
+    var extension = unit.declarations[0] as ExtensionDeclaration;
+    expect(extension.members, hasLength(0));
+  }
+
   void test_missing_on() {
     var unit = parseCompilationUnit('extension E', errors: [
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
@@ -1802,133 +1830,6 @@
   }
 }
 
-@reflectiveTest
-class VarianceParserTest_Fasta extends FastaParserTestCase {
-  @override
-  CompilationUnit parseCompilationUnit(String content,
-      {List<ErrorCode> codes,
-      List<ExpectedError> errors,
-      FeatureSet featureSet}) {
-    return super.parseCompilationUnit(content,
-        codes: codes,
-        errors: errors,
-        featureSet: featureSet ??
-            FeatureSet.forTesting(
-              sdkVersion: '2.5.0',
-              additionalFeatures: [Feature.variance],
-            ));
-  }
-
-  void test_class_enabled_single() {
-    var unit = parseCompilationUnit('class A<in T> { }');
-    expect(unit.declarations, hasLength(1));
-    var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name.name, 'A');
-    expect(classDecl.typeParameters.typeParameters, hasLength(1));
-    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
-  }
-
-  void test_class_enabled_multipleVariances() {
-    var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
-      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
-      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
-    ]);
-    expect(unit.declarations, hasLength(1));
-    var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name.name, 'A');
-    expect(classDecl.typeParameters.typeParameters, hasLength(1));
-    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
-  }
-
-  void test_class_disabled_single() {
-    parseCompilationUnit('class A<out T> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_class_disabled_multiple() {
-    parseCompilationUnit('class A<in T, inout U, out V> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_mixin_enabled_single() {
-    var unit = parseCompilationUnit('mixin A<inout T> { }');
-    expect(unit.declarations, hasLength(1));
-    var mixinDecl = unit.declarations[0] as MixinDeclaration;
-    expect(mixinDecl.name.name, 'A');
-    expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
-    expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
-  }
-
-  void test_mixin_disabled_single() {
-    parseCompilationUnit('mixin A<inout T> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_mixin_disabled_multiple() {
-    parseCompilationUnit('mixin A<inout T, out U> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_typedef_enabled() {
-    parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
-    ]);
-  }
-
-  void test_typedef_disabled() {
-    parseCompilationUnit('typedef A<inout X> = X Function(X);',
-        errors: [
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_list_enabled() {
-    parseCompilationUnit('List<out String> stringList = [];', errors: [
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
-    ]);
-  }
-
-  void test_list_disabled() {
-    parseCompilationUnit('List<out String> stringList = [];',
-        errors: [
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_function_enabled() {
-    parseCompilationUnit('void A(in int value) {}', errors: [
-      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
-    ]);
-  }
-
-  void test_function_disabled() {
-    parseCompilationUnit('void A(in int value) {}',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-}
-
 /**
  * Implementation of [AbstractParserTestCase] specialized for testing the
  * Fasta parser.
@@ -2959,6 +2860,21 @@
     parseCompilationUnit('f() { var x = g!.x + 7; }');
   }
 
+  void test_nullCheckBeforeIndex() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var expression = statement.expression as IndexExpression;
+    expect(expression.index.toSource(), 'arg');
+    var propertyAccess = expression.target as PropertyAccess;
+    expect(propertyAccess.propertyName.toSource(), 'baz');
+    var target = propertyAccess.target as PostfixExpression;
+    expect(target.operand.toSource(), 'foo.bar');
+    expect(target.operator.lexeme, '!');
+  }
+
   void test_nullCheckBeforeMethodCall() {
     parseCompilationUnit('f() { var x = g!.m() + 7; }');
   }
@@ -3119,21 +3035,6 @@
     expect(target.operand.toSource(), "foo");
   }
 
-  void test_nullCheckBeforeIndex() {
-    // https://github.com/dart-lang/sdk/issues/37708
-    var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
-    var funct = unit.declarations[0] as FunctionDeclaration;
-    var body = funct.functionExpression.body as BlockFunctionBody;
-    var statement = body.block.statements[0] as ExpressionStatement;
-    var expression = statement.expression as IndexExpression;
-    expect(expression.index.toSource(), 'arg');
-    var propertyAccess = expression.target as PropertyAccess;
-    expect(propertyAccess.propertyName.toSource(), 'baz');
-    var target = propertyAccess.target as PostfixExpression;
-    expect(target.operand.toSource(), 'foo.bar');
-    expect(target.operator.lexeme, '!');
-  }
-
   void test_nullCheckOnLiteral_disabled() {
     parseCompilationUnit('f() { var x = 0!; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
@@ -4356,3 +4257,130 @@
     expect(declarationList.variables, hasLength(1));
   }
 }
+
+@reflectiveTest
+class VarianceParserTest_Fasta extends FastaParserTestCase {
+  @override
+  CompilationUnit parseCompilationUnit(String content,
+      {List<ErrorCode> codes,
+      List<ExpectedError> errors,
+      FeatureSet featureSet}) {
+    return super.parseCompilationUnit(content,
+        codes: codes,
+        errors: errors,
+        featureSet: featureSet ??
+            FeatureSet.forTesting(
+              sdkVersion: '2.5.0',
+              additionalFeatures: [Feature.variance],
+            ));
+  }
+
+  void test_class_disabled_multiple() {
+    parseCompilationUnit('class A<in T, inout U, out V> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_class_disabled_single() {
+    parseCompilationUnit('class A<out T> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_class_enabled_multipleVariances() {
+    var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
+      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
+      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
+    ]);
+    expect(unit.declarations, hasLength(1));
+    var classDecl = unit.declarations[0] as ClassDeclaration;
+    expect(classDecl.name.name, 'A');
+    expect(classDecl.typeParameters.typeParameters, hasLength(1));
+    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
+  }
+
+  void test_class_enabled_single() {
+    var unit = parseCompilationUnit('class A<in T> { }');
+    expect(unit.declarations, hasLength(1));
+    var classDecl = unit.declarations[0] as ClassDeclaration;
+    expect(classDecl.name.name, 'A');
+    expect(classDecl.typeParameters.typeParameters, hasLength(1));
+    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
+  }
+
+  void test_function_disabled() {
+    parseCompilationUnit('void A(in int value) {}',
+        errors: [
+          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_function_enabled() {
+    parseCompilationUnit('void A(in int value) {}', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
+    ]);
+  }
+
+  void test_list_disabled() {
+    parseCompilationUnit('List<out String> stringList = [];',
+        errors: [
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_list_enabled() {
+    parseCompilationUnit('List<out String> stringList = [];', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+    ]);
+  }
+
+  void test_mixin_disabled_multiple() {
+    parseCompilationUnit('mixin A<inout T, out U> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_mixin_disabled_single() {
+    parseCompilationUnit('mixin A<inout T> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_mixin_enabled_single() {
+    var unit = parseCompilationUnit('mixin A<inout T> { }');
+    expect(unit.declarations, hasLength(1));
+    var mixinDecl = unit.declarations[0] as MixinDeclaration;
+    expect(mixinDecl.name.name, 'A');
+    expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
+    expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
+  }
+
+  void test_typedef_disabled() {
+    parseCompilationUnit('typedef A<inout X> = X Function(X);',
+        errors: [
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_typedef_enabled() {
+    parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 1ff1558..6b7c83e 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -222,7 +222,7 @@
     if (token == null) {
       return;
     }
-    Token previousToken = null;
+    Token previousToken;
     int previousEnd = -1;
     Token currentToken = token;
     while (currentToken != null && currentToken.type != TokenType.EOF) {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index b1a5532..eb0cec2 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1212,8 +1212,8 @@
       _assertHasPrevious(clone);
     }
     Token stopOriginalToken = originalNode.endToken.next;
-    Token skipCloneComment = null;
-    Token skipOriginalComment = null;
+    Token skipCloneComment;
+    Token skipOriginalComment;
     while (original != stopOriginalToken) {
       expect(clone, isNotNull);
       _assertEqualToken(clone, original);
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 03fb7a6..cfe7454 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -65,7 +65,7 @@
    * The path to the default SDK, or `null` if the test has not explicitly
    * invoked [createDefaultSdk].
    */
-  String defaultSdkPath = null;
+  String defaultSdkPath;
 
   _MockLintRule _mockLintRule;
   _MockLintRule _mockLintRule2;
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 46ac748..29aeeb5 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -26,7 +26,7 @@
  * Finds an [Element] with the given [name].
  */
 Element findChildElement(Element root, String name, [ElementKind kind]) {
-  Element result = null;
+  Element result;
   root.accept(new _ElementVisitorFunctionWrapper((Element element) {
     if (element.name != name) {
       return;
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index 7c00d1f..1e9c3fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -56,6 +56,7 @@
 }
 ''', [
       error(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 12, 0),
       error(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1),
       error(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 16, 1),
     ]);
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index e76fb1b..e9b17ee 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
@@ -316,6 +317,23 @@
     validateBinaryExpression();
   }
 
+  test_operator_onTearoff() async {
+    // https://github.com/dart-lang/sdk/issues/38653
+    await assertErrorsInCode('''
+f(){
+  E(null).v++;
+}
+extension E on Object{
+  v() {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 15, 1),
+    ]);
+    findDeclarationAndOverride(
+        declarationName: 'E ', overrideSearch: 'E(null)');
+    validateOverride();
+  }
+
   test_operator_prefix_noTypeArguments() async {
     newFile('/test/lib/lib.dart', content: '''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index c2520f8..c617a00 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -103,6 +103,7 @@
     expect(value.getField('a').getField('f').toIntValue(), 42);
   }
 
+  @FailingTest(reason: 'Reverted because of dartbug.com/38565')
   test_sameLibrary_genericClass_constructor_unnamed() async {
     await assertNoErrorsInCode(r'''
 class A<T> {
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index 9d2253f..97b6c70 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -36,7 +36,7 @@
     // mismatch. Furthermore, the error message should mention both _A and the
     // filenames so the user can figure out what's going on.
     String message = result.errors[0].message;
-    expect(message.indexOf("_A") >= 0, isTrue);
+    expect(message.contains("_A"), isTrue);
   }
 
   test_annotation_namedConstructor() async {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 6831be1..4418dfc 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -69,15 +69,17 @@
   bool annotateNullability: false,
 }) {
   var writer = new _ElementWriter(
-      withCodeRanges: withCodeRanges,
-      withConstElements: withConstElements,
-      withExportScope: withExportScope,
-      withFullyResolvedAst: withFullyResolvedAst,
-      withOffsets: withOffsets,
-      withSyntheticAccessors: withSyntheticAccessors,
-      withSyntheticFields: withSyntheticFields,
-      withTypes: withTypes,
-      annotateNullability: annotateNullability);
+    selfUriStr: '${library.source.uri}',
+    withCodeRanges: withCodeRanges,
+    withConstElements: withConstElements,
+    withExportScope: withExportScope,
+    withFullyResolvedAst: withFullyResolvedAst,
+    withOffsets: withOffsets,
+    withSyntheticAccessors: withSyntheticAccessors,
+    withSyntheticFields: withSyntheticFields,
+    withTypes: withTypes,
+    annotateNullability: annotateNullability,
+  );
   writer.writeLibraryElement(library);
 
   String actualText = writer.buffer.toString();
@@ -138,6 +140,7 @@
  * Writes the canonical text presentation of elements.
  */
 class _ElementWriter {
+  final String selfUriStr;
   final bool withCodeRanges;
   final bool withExportScope;
   final bool withFullyResolvedAst;
@@ -149,16 +152,20 @@
   final bool annotateNullability;
   final StringBuffer buffer = new StringBuffer();
 
-  _ElementWriter(
-      {this.withCodeRanges,
-      this.withConstElements: true,
-      this.withExportScope: false,
-      this.withFullyResolvedAst: false,
-      this.withOffsets: false,
-      this.withSyntheticAccessors: false,
-      this.withSyntheticFields: false,
-      this.withTypes: false,
-      this.annotateNullability: false});
+  String indent = '';
+
+  _ElementWriter({
+    this.selfUriStr,
+    this.withCodeRanges,
+    this.withConstElements: true,
+    this.withExportScope: false,
+    this.withFullyResolvedAst: false,
+    this.withOffsets: false,
+    this.withSyntheticAccessors: false,
+    this.withSyntheticFields: false,
+    this.withTypes: false,
+    this.annotateNullability: false,
+  });
 
   bool isDynamicType(DartType type) => type is DynamicTypeImpl;
 
@@ -226,25 +233,35 @@
 
     buffer.writeln(' {');
 
-    e.fields.forEach(writePropertyInducingElement);
-    e.accessors.forEach(writePropertyAccessorElement);
+    _withIndent(() {
+      e.fields.forEach(writePropertyInducingElement);
+      e.accessors.forEach(writePropertyAccessorElement);
 
-    if (e.isEnum) {
-      expect(e.constructors, isEmpty);
-    } else {
-      expect(e.constructors, isNotEmpty);
-    }
+      if (e.isEnum) {
+        expect(e.constructors, isEmpty);
+      } else {
+        expect(e.constructors, isNotEmpty);
+      }
 
-    if (e.constructors.length == 1 &&
-        e.constructors[0].isSynthetic &&
-        e.mixins.isEmpty) {
-      expect(e.constructors[0].parameters, isEmpty);
-    } else {
-      e.constructors.forEach(writeConstructorElement);
-    }
+      if (e.constructors.length == 1 &&
+          e.constructors[0].isSynthetic &&
+          e.mixins.isEmpty) {
+        expect(e.constructors[0].parameters, isEmpty);
+      } else {
+        e.constructors.forEach(writeConstructorElement);
+      }
 
-    e.methods.forEach(writeMethodElement);
+      e.methods.forEach(writeMethodElement);
+    });
+
     buffer.writeln('}');
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        _writeResolvedTypeParameters(e.typeParameters);
+      });
+    }
   }
 
   void writeCodeRange(Element e) {
@@ -292,16 +309,28 @@
       }
     }
 
-    if (e is ConstructorElementImpl) {
-      if (e.constantInitializers != null) {
-        writeList(' : ', '', e.constantInitializers, ', ', writeNode);
+    var initializers = (e as ConstructorElementImpl).constantInitializers;
+    if (withFullyResolvedAst) {
+      buffer.writeln(';');
+      if (initializers != null && initializers.isNotEmpty) {
+        _withIndent(() {
+          _writelnWithIndent('constantInitializers');
+          _withIndent(() {
+            for (var initializer in initializers) {
+              _writeResolvedNode(initializer);
+            }
+          });
+        });
       }
+    } else {
+      if (initializers != null) {
+        writeList(' : ', '', initializers, ', ', writeNode);
+      }
+      buffer.writeln(';');
     }
 
     expect(e.isAsynchronous, isFalse);
     expect(e.isGenerator, isFalse);
-
-    buffer.writeln(';');
   }
 
   void writeDocumentation(Element e, [String prefix = '']) {
@@ -355,10 +384,21 @@
     }
 
     buffer.writeln(' {');
-    e.fields.forEach(writePropertyInducingElement);
-    e.accessors.forEach(writePropertyAccessorElement);
-    e.methods.forEach(writeMethodElement);
+
+    _withIndent(() {
+      e.fields.forEach(writePropertyInducingElement);
+      e.accessors.forEach(writePropertyAccessorElement);
+      e.methods.forEach(writeMethodElement);
+    });
+
     buffer.writeln('}');
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        _writeResolvedTypeParameters(e.typeParameters);
+      });
+    }
   }
 
   void writeFunctionElement(FunctionElement e) {
@@ -488,6 +528,10 @@
   }
 
   void writeMetadata(Element e, String prefix, String separator) {
+    if (withFullyResolvedAst) {
+      return;
+    }
+
     if (e.metadata.isNotEmpty) {
       writeList(prefix, '', e.metadata, '$separator$prefix', (a) {
         writeNode((a as ElementAnnotationImpl).annotationAst);
@@ -520,6 +564,13 @@
     } else {
       buffer.writeln(' {}');
     }
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedTypeParameters(e.typeParameters);
+        _writeResolvedMetadata(e.metadata);
+      });
+    }
   }
 
   void writeName(Element e) {
@@ -540,14 +591,7 @@
     }
   }
 
-  void writeNode(AstNode e, {String indent: '', Expression enclosing}) {
-    if (withFullyResolvedAst) {
-      buffer.writeln();
-      var printer = ResolvedAstPrinter(buffer, indent);
-      e.accept(printer);
-      return;
-    }
-
+  void writeNode(AstNode e, {Expression enclosing}) {
     bool needsParenthesis = e is Expression &&
         enclosing != null &&
         e.precedence < enclosing.precedence;
@@ -961,25 +1005,35 @@
 
     writeVariableTypeInferenceError(e);
 
-    if (e is ConstVariableElement) {
-      Expression initializer = (e as ConstVariableElement).constantInitializer;
-      if (initializer != null) {
-        buffer.write(' = ');
-        writeNode(
-          initializer,
-          indent: ' ' * (e is FieldElement ? 4 : 2),
-        );
-        if (withFullyResolvedAst) {
-          return;
+    if (withFullyResolvedAst) {
+      buffer.writeln(';');
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        if (e is ConstVariableElement) {
+          var initializer = (e as ConstVariableElement).constantInitializer;
+          if (initializer != null) {
+            _writelnWithIndent('constantInitializer');
+            _withIndent(() {
+              _writeResolvedNode(initializer);
+            });
+          }
+        }
+      });
+    } else {
+      if (e is ConstVariableElement) {
+        Expression initializer =
+            (e as ConstVariableElement).constantInitializer;
+        if (initializer != null) {
+          buffer.write(' = ');
+          writeNode(initializer);
         }
       }
+      buffer.writeln(';');
     }
 
     // TODO(scheglov) Paul: One of the things that was hardest to get right
     // when resynthesizing the element model was the synthetic function for the
     // initializer.  Can we write that out (along with its return type)?
-
-    buffer.writeln(';');
   }
 
   void writeType(DartType type) {
@@ -1047,7 +1101,9 @@
   }
 
   void writeTypeParameterElements(List<TypeParameterElement> elements) {
-    writeList('<', '>', elements, ', ', writeTypeParameterElement);
+    if (!withFullyResolvedAst) {
+      writeList('<', '>', elements, ', ', writeTypeParameterElement);
+    }
   }
 
   void writeUnitElement(CompilationUnitElement e) {
@@ -1135,6 +1191,18 @@
     return components.join(';');
   }
 
+  void _withIndent(void Function() f) {
+    var indent = this.indent;
+    this.indent = '$indent  ';
+    f();
+    this.indent = indent;
+  }
+
+  void _writelnWithIndent(String line) {
+    buffer.write(indent);
+    buffer.writeln(line);
+  }
+
   bool _writeParameters(Iterable<ParameterElement> parameters, bool commaNeeded,
       String prefix, String suffix) {
     if (parameters.isEmpty) return commaNeeded;
@@ -1160,6 +1228,44 @@
     buffer.write(suffix);
     return commaNeeded;
   }
+
+  void _writeResolvedMetadata(List<ElementAnnotation> metadata) {
+    if (metadata.isNotEmpty) {
+      _writelnWithIndent('metadata');
+      _withIndent(() {
+        for (ElementAnnotationImpl annotation in metadata) {
+          _writeResolvedNode(annotation.annotationAst);
+        }
+      });
+    }
+  }
+
+  void _writeResolvedNode(AstNode node) {
+    buffer.write(indent);
+    node.accept(
+      ResolvedAstPrinter(
+        selfUriStr: selfUriStr,
+        sink: buffer,
+        indent: indent,
+      ),
+    );
+  }
+
+  void _writeResolvedTypeParameters(List<TypeParameterElement> elements) {
+    if (elements.isNotEmpty) {
+      _writelnWithIndent('typeParameters');
+      _withIndent(() {
+        for (TypeParameterElementImpl e in elements) {
+          _writelnWithIndent(e.name);
+          _withIndent(() {
+            _writelnWithIndent('bound: ${e.bound}');
+            _writelnWithIndent('defaultType: ${e.defaultType}');
+            _writeResolvedMetadata(e.metadata);
+          });
+        }
+      });
+    }
+  }
 }
 
 class _Replacement {
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 551cad1..93a5e30 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -4,26 +4,77 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
 
 /// Prints AST as a tree, with properties and children.
 class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
-  StringSink _sink;
+  final String _selfUriStr;
+  final StringSink _sink;
   String _indent = '';
 
-  ResolvedAstPrinter(StringSink sink, String indent)
-      : _sink = sink,
+  ResolvedAstPrinter({
+    @required String selfUriStr,
+    @required StringSink sink,
+    @required String indent,
+  })  : _selfUriStr = selfUriStr,
+        _sink = sink,
         _indent = indent;
 
   @override
+  void visitAnnotation(Annotation node) {
+    _writeln('Annotation');
+    _withIndent(() {
+      _writeNode('arguments', node.arguments);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('element', node.element);
+      _writeNode('name', node.name);
+    });
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    _writeln('ArgumentList');
+    _withIndent(() {
+      _writeNodeList('arguments', node.arguments);
+    });
+  }
+
+  @override
   void visitCompilationUnit(CompilationUnit node) {
     super.visitCompilationUnit(node);
   }
 
   @override
-  void visitIntegerLiteral(IntegerLiteral node) {
-    _writeln('IntegerLiteral(${node.literal.lexeme})');
+  void visitConstructorName(ConstructorName node) {
+    _writeln('ConstructorName');
     _withIndent(() {
-      _writeln2('staticType: ', node.staticType);
+      _writeNode('name', node.name);
+      _writeNode('type', node.type);
+    });
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _writeln('InstanceCreationExpression');
+    _withIndent(() {
+      _writeNode('argumentList', node.argumentList);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('staticElement', node.staticElement);
+      _writeType('staticType', node.staticType);
+    });
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    _writeln('IntegerLiteral');
+    _withIndent(() {
+      _writelnWithIndent('literal: ${node.literal}');
+      _writeType('staticType', node.staticType);
     });
   }
 
@@ -31,13 +82,74 @@
   void visitListLiteral(ListLiteral node) {
     _writeln('ListLiteral');
     _withIndent(() {
-      _writeln2('isConst: ', node.isConst);
-      _writeln2('staticType: ', node.staticType);
-      _writeTypeArgumentList('typeArguments', node.typeArguments);
       _writeNodeList('elements', node.elements);
+      _writeType('staticType', node.staticType);
+      _writeNode('typeArguments', node.typeArguments);
     });
   }
 
+  @override
+  void visitRedirectingConstructorInvocation(
+    RedirectingConstructorInvocation node,
+  ) {
+    _writeln('RedirectingConstructorInvocation');
+    _withIndent(() {
+      _writeNode('argumentList', node.argumentList);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('staticElement', node.staticElement);
+    });
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    _writeln('SimpleIdentifier');
+    _withIndent(() {
+      _writeAuxiliaryElements('auxiliaryElements', node.auxiliaryElements);
+      _writeElement('staticElement', node.staticElement);
+      _writeType('staticType', node.staticType);
+      _writelnWithIndent('token: ${node.token}');
+    });
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writeln('SuperConstructorInvocation');
+    _withIndent(() {
+      _writeNode('argumentList', node.argumentList);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('staticElement', node.staticElement);
+    });
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    _writeln('TypeName');
+    _withIndent(() {
+      _writeNode('name', node.name);
+      _writeType('type', node.type);
+      _writeNode('typeArguments', node.typeArguments);
+    });
+  }
+
+  String _referenceToString(Reference reference) {
+    if (reference.parent.name == '@unit') {
+      var libraryUriStr = reference.parent.parent.name;
+      if (libraryUriStr == _selfUriStr) {
+        return 'self';
+      }
+      return libraryUriStr;
+    }
+
+    var name = reference.name;
+    if (name.startsWith('@')) {
+      return _referenceToString(reference.parent);
+    }
+    if (name.isEmpty) {
+      name = '•';
+    }
+    return _referenceToString(reference.parent) + '::$name';
+  }
+
   void _withIndent(void Function() f) {
     var indent = _indent;
     _indent = '$_indent  ';
@@ -45,32 +157,64 @@
     _indent = indent;
   }
 
+  void _writeAuxiliaryElements(String name, AuxiliaryElements elements) {
+    if (elements != null) {
+      throw UnimplementedError();
+    }
+  }
+
+  void _writeElement(String name, Element element) {
+    _sink.write(_indent);
+    _sink.write('$name: ');
+    if (element == null) {
+      _sink.writeln('<null>');
+    } else if (element is Member) {
+      _sink.writeln(_nameOfMemberClass(element));
+      _withIndent(() {
+        _writeElement('base', element.baseElement);
+        _writelnWithIndent('substitution: ${element.substitution.map}');
+      });
+    } else {
+      var reference = (element as ElementImpl).reference;
+      var referenceStr = _referenceToString(reference);
+      _sink.writeln(referenceStr);
+    }
+  }
+
   void _writeln(String line) {
-    _sink.write('$_indent');
     _sink.writeln(line);
   }
 
-  void _writeln2(String prefix, Object o) {
-    _sink.write('$_indent');
-    _sink.write(prefix);
-    _sink.writeln(o);
+  void _writelnWithIndent(String line) {
+    _sink.write(_indent);
+    _sink.writeln(line);
+  }
+
+  void _writeNode(String name, AstNode node) {
+    if (node != null) {
+      _sink.write(_indent);
+      _sink.write('$name: ');
+      node.accept(this);
+    }
   }
 
   void _writeNodeList(String name, NodeList nodeList) {
     if (nodeList.isNotEmpty) {
-      _writeln(name);
+      _writelnWithIndent(name);
       _withIndent(() {
-        nodeList.accept(this);
+        for (var node in nodeList) {
+          _sink.write(_indent);
+          node.accept(this);
+        }
       });
     }
   }
 
-  void _writeTypeArgumentList(String name, TypeArgumentList node) {
-    if (node != null) {
-      _writeln(name);
-      _withIndent(() {
-        node.arguments?.accept(this);
-      });
-    }
+  void _writeType(String name, DartType type) {
+    _writelnWithIndent('$name: $type');
+  }
+
+  static String _nameOfMemberClass(Member member) {
+    return '${member.runtimeType}';
   }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 6785245..618e653 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -33,9 +33,6 @@
   /// The shared SDK bundle, computed once and shared among test invocations.
   static LinkedNodeBundle _sdkBundle;
 
-  @override
-  bool get isAstBasedSummary => true;
-
   LinkedNodeBundle get sdkBundle {
     if (_sdkBundle != null) return _sdkBundle;
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 86a1ada..54294ea 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1256,21 +1256,12 @@
 class C<T extends D> {}
 class D<T extends C> {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 notSimplyBounded class C<T extends D<dynamic>> {
 }
 notSimplyBounded class D<T extends C<dynamic>> {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-notSimplyBounded class C<T extends D<dynamic>> {
-}
-notSimplyBounded class D<T extends C<D<dynamic>>> {
-}
-''');
-    }
   }
 
   test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
@@ -1353,21 +1344,12 @@
 typedef F(G value);
 typedef G(F value);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(dynamic)) value);
 notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic) value);
 notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic Function(dynamic)))> {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(...)) value);
-notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic Function(...)) value);
-notSimplyBounded class C<T extends dynamic Function(dynamic Function(...))> {
-}
-''');
-    }
   }
 
   test_class_notSimplyBounded_self() async {
@@ -2574,10 +2556,9 @@
   P2<int>(),
 ];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 class P<T> {
   const P();
 }
@@ -2592,27 +2573,7 @@
         P2/*location: test.dart;P2*/<
         int/*location: dart:core;int*/>()];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(
-          library,
-          '''
-class P<T> {
-  const P();
-}
-class P1<T> extends P<T> {
-  const P1();
-}
-class P2<T> extends P<T> {
-  const P2();
-}
-const List<P<dynamic>> values = const /*typeArgs=dynamic*/[const /*typeArgs=dynamic*/
-        P1/*location: test.dart;P1*/(), const
-        P2/*location: test.dart;P2*/<
-        int/*location: dart:core;int*/>()];
-''',
-          withTypes: true);
-    }
+        withTypes: true);
   }
 
   test_const_invalid_field_const() async {
@@ -2728,8 +2689,7 @@
 import 'a.dart' as p;
 const V = const p.C<int, String>.named(1, '222');
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C<int, String> V = const
         p/*location: test.dart;p*/.
@@ -2738,16 +2698,6 @@
         String/*location: dart:core;String*/>.
         named/*location: a.dart;C;named*/(1, '222');
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: a.dart;C;named*/(1, '222');
-''');
-    }
   }
 
   test_const_invokeConstructor_generic_noTypeArguments() async {
@@ -2813,8 +2763,7 @@
 import 'a.dart' as p;
 const V = const p.C<int, String>();
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C<int, String> V = const
         p/*location: test.dart;p*/.
@@ -2822,15 +2771,6 @@
         int/*location: dart:core;int*/,
         String/*location: dart:core;String*/>();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    }
   }
 
   test_const_invokeConstructor_named() async {
@@ -2840,8 +2780,7 @@
 }
 const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   const C.named(bool a, int b, int c, {String d}, {double e});
 }
@@ -2851,18 +2790,6 @@
         d/*location: test.dart;C;named;d*/: 'ccc',
         e/*location: test.dart;C;named;e*/: 3.4);
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  const C.named(bool a, int b, int c, {String d}, {double e});
-}
-const C V = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(true, 1, 2,
-        d/*location: null*/: 'ccc',
-        e/*location: null*/: 3.4);
-''');
-    }
   }
 
   test_const_invokeConstructor_named_imported() async {
@@ -2893,22 +2820,13 @@
 import 'a.dart' as p;
 const V = const p.C.named();
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C V = const
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/.
         named/*location: a.dart;C;named*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved() async {
@@ -2916,23 +2834,13 @@
 class C {}
 const V = const C.named();
 ''', allowErrors: true);
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
 }
 const C V = const
         C/*location: test.dart;C*/.
         named/*location: null*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-}
-const dynamic V = const
-        C/*location: test.dart;C*/.
-        named/*location: null*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved2() async {
@@ -2955,23 +2863,13 @@
 import 'a.dart' as p;
 const V = const p.C.named();
 ''', allowErrors: true);
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C V = const
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/.
         named/*location: null*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        named/*location: null*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved4() async {
@@ -3006,23 +2904,13 @@
 class C<T> {}
 const V = const C.named();
 ''', allowErrors: true);
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C<T> {
 }
 const C<dynamic> V = const
         C/*location: test.dart;C*/.
         named/*location: null*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-class C<T> {
-}
-const dynamic V = const
-        C/*location: test.dart;C*/.
-        named/*location: null*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_unnamed() async {
@@ -3068,20 +2956,12 @@
 import 'a.dart' as p;
 const V = const p.C();
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C V = const
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
-        C/*location: a.dart;C*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_unnamed_unresolved() async {
@@ -3282,63 +3162,40 @@
     var library = await checkLibrary('''
 const Object x = const [1];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const /*typeArgs=int*/[1];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[1];
-''');
-    }
+        withTypes: true);
   }
 
   test_const_list_spread() async {
     var library = await checkLibrary('''
 const Object x = const <int>[...<int>[1]];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>[...<
         int/*location: dart:core;int*/>[1]];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[...const <
-        int/*location: dart:core;int*/>[1]];
-''');
-    }
+        withTypes: true);
   }
 
   test_const_list_spread_null_aware() async {
     var library = await checkLibrary('''
 const Object x = const <int>[...?<int>[1]];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>[...?<
         int/*location: dart:core;int*/>[1]];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[...?const <
-        int/*location: dart:core;int*/>[1]];
-''');
-    }
+        withTypes: true);
   }
 
   test_const_map_if() async {
@@ -3376,72 +3233,44 @@
     var library = await checkLibrary('''
 const Object x = const {1: 1.0};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const /*typeArgs=int,double*/{1: 1.0}/*isMap*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        double/*location: dart:core;double*/>{1: 1.0}/*isMap*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_map_spread() async {
     var library = await checkLibrary('''
 const Object x = const <int, int>{...<int, int>{1: 2}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{...<
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{...const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_map_spread_null_aware() async {
     var library = await checkLibrary('''
 const Object x = const <int, int>{...?<int, int>{1: 2}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{...?<
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{...?const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
@@ -3938,63 +3767,40 @@
     var library = await checkLibrary('''
 const Object x = const {1};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const /*typeArgs=int*/{1}/*isSet*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>{1}/*isSet*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_set_spread() async {
     var library = await checkLibrary('''
 const Object x = const <int>{...<int>{1}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>{...<
         int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>{...const <
-        int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_set_spread_null_aware() async {
     var library = await checkLibrary('''
 const Object x = const <int>{...?<int>{1}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>{...?<
         int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>{...?const <
-        int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_topLevel_binary() async {
@@ -4044,30 +3850,18 @@
     var library = await checkLibrary(r'''
 const vConditional = (1 == 2) ? 11 : 22;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 const int vConditional = (1 == 2) ? 11 : 22;
 ''');
-    } else {
-      checkElementText(library, r'''
-const int vConditional = 1 == 2 ? 11 : 22;
-''');
-    }
   }
 
   test_const_topLevel_identical() async {
     var library = await checkLibrary(r'''
 const vIdentical = (1 == 2) ? 11 : 22;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 const int vIdentical = (1 == 2) ? 11 : 22;
 ''');
-    } else {
-      checkElementText(library, r'''
-const int vIdentical = 1 == 2 ? 11 : 22;
-''');
-    }
   }
 
   test_const_topLevel_ifNull() async {
@@ -4159,16 +3953,9 @@
     var library = await checkLibrary(r'''
 const c = throw 42;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 const dynamic c = throw 42;
 ''');
-    } else {
-      // This is a bug.
-      checkElementText(library, r'''
-const dynamic c;
-''');
-    }
   }
 
   test_const_topLevel_typedList() async {
@@ -4219,20 +4006,12 @@
 import 'a.dart' as p;
 const v = const <p.C>[];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const List<C> v = const <
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/>[];
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const List<C> v = const <
-        C/*location: a.dart;C*/>[];
-''');
-    }
   }
 
   test_const_topLevel_typedList_typedefArgument() async {
@@ -4240,21 +4019,11 @@
 typedef int F(String id);
 const v = const <F>[];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 typedef F = int Function(String id);
 const List<int Function(String)> v = const <
         F/*location: test.dart;F*/>[];
 ''');
-    } else {
-      // This is wrong.
-      // `F` must be the reference to `typedef F` element, not the type.
-      checkElementText(library, r'''
-typedef F = int Function(String id);
-const List<int Function(String)> v = const <
-        null/*location: test.dart;F;-*/>[];
-''');
-    }
   }
 
   test_const_topLevel_typedMap() async {
@@ -4370,24 +4139,13 @@
   static const b = null;
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   static const dynamic a =
         b/*location: test.dart;C;b?*/;
   static const dynamic b = null;
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic a =
-        C/*location: test.dart;C*/.
-        b/*location: test.dart;C;b?*/;
-  static const dynamic b = null;
-}
-''');
-    }
   }
 
   test_constExpr_pushReference_staticMethod_simpleIdentifier() async {
@@ -4397,24 +4155,13 @@
   static m() {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   static const dynamic Function() a =
         m/*location: test.dart;C;m*/;
   static dynamic m() {}
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic Function() a =
-        C/*location: test.dart;C*/.
-        m/*location: test.dart;C;m*/;
-  static dynamic m() {}
-}
-''');
-    }
   }
 
   test_constructor_documented() async {
@@ -4527,8 +4274,7 @@
    : this(A<Function()>());
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A<T> {
   const A();
 }
@@ -4538,7 +4284,35 @@
         A/*location: test.dart;A*/<Function()>());
 }
 ''');
-    }
+  }
+
+  test_constructor_initializers_superInvocation_argumentContextType() async {
+    var library = await checkLibrary('''
+class A {
+  const A(List<String> values);
+}
+class B extends A {
+  const B() : super(const []);
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A(List<String> values);
+}
+class B extends A {
+  const B();
+    constantInitializers
+      SuperConstructorInvocation
+        argumentList: ArgumentList
+          arguments
+            ListLiteral
+              staticType: List<String>
+        staticElement: self::A::•
+}
+''',
+        withFullyResolvedAst: true);
   }
 
   test_constructor_initializers_superInvocation_named() async {
@@ -4590,8 +4364,7 @@
   const C() : super.aaa(1, b: 2);
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A {
   const A.aaa(dynamic a, {int b});
 }
@@ -4601,18 +4374,6 @@
         b/*location: test.dart;A;aaa;b*/: 2);
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class A {
-  const A.aaa(dynamic a, {int b});
-}
-class C extends A {
-  const C() : super.
-        aaa/*location: test.dart;A;aaa*/(1,
-        b/*location: null*/: 2);
-}
-''');
-    }
   }
 
   test_constructor_initializers_superInvocation_unnamed() async {
@@ -4634,6 +4395,31 @@
 ''');
   }
 
+  test_constructor_initializers_thisInvocation_argumentContextType() async {
+    var library = await checkLibrary('''
+class A {
+  const A(List<String> values);
+  const A.empty() : this(const []);
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A(List<String> values);
+  const A.empty() = A;
+    constantInitializers
+      RedirectingConstructorInvocation
+        argumentList: ArgumentList
+          arguments
+            ListLiteral
+              staticType: List<String>
+        staticElement: self::A::•
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_constructor_initializers_thisInvocation_named() async {
     var library = await checkLibrary('''
 class C {
@@ -4657,8 +4443,7 @@
   const C.named(a, {int b});
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   const C() = C.named : this.
         named/*location: test.dart;C;named*/(1,
@@ -4666,16 +4451,6 @@
   const C.named(dynamic a, {int b});
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  const C() = C.named : this.
-        named/*location: test.dart;C;named*/(1,
-        b/*location: null*/: 2);
-  const C.named(dynamic a, {int b});
-}
-''');
-    }
   }
 
   test_constructor_initializers_thisInvocation_unnamed() async {
@@ -5042,21 +4817,12 @@
   C() : this.named();
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   C.named();
   C();
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  C.named();
-  C() = C.named;
-}
-''');
-    }
   }
 
   test_constructor_redirected_thisInvocation_unnamed() async {
@@ -5096,21 +4862,12 @@
   C.named() : this();
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   C();
   C.named();
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  C();
-  C.named() = C;
-}
-''');
-    }
   }
 
   test_constructor_withCycles_const() async {
@@ -5194,8 +4951,7 @@
   void foo({a: const A<Function()>()}) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A<T> {
   const A();
 }
@@ -5204,7 +4960,6 @@
         A/*location: test.dart;A*/<Function()>()}) {}
 }
 ''');
-    }
   }
 
   test_defaultValue_refersToExtension_method_inside() async {
@@ -5259,10 +5014,9 @@
   const C([B<T> b = const B()]);
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
@@ -5271,18 +5025,7 @@
         B/*location: test.dart;B*/()]);
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  const C([B<T> b = const
-        B/*location: test.dart;B*/()]);
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_constructor2() async {
@@ -5295,10 +5038,9 @@
   const C([A<T> a = const B()]);
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 abstract class A<T> {
 }
 class B<T> implements A<T> {
@@ -5309,20 +5051,7 @@
         B/*location: test.dart;B*/()]);
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-abstract class A<T> {
-}
-class B<T> implements A<T> {
-  const B();
-}
-class C<T> implements A<Iterable<T>> {
-  const C([A<T> a = const
-        B/*location: test.dart;B*/()]);
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_functionG() async {
@@ -5332,26 +5061,16 @@
 }
 void foo<T>([B<T> b = const B()]) {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
 void foo<T>([B<T> b = const /*typeArgs=Null*/
         B/*location: test.dart;B*/()]) {}
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_methodG() async {
@@ -5363,10 +5082,9 @@
   void foo<T>([B<T> b = const B()]) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
@@ -5375,18 +5093,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C {
-  void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_methodG_classG() async {
@@ -5398,10 +5105,9 @@
   void foo<E2>([B<E1, E2> b = const B()]) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T1, T2> {
   const B();
 }
@@ -5410,18 +5116,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T1, T2> {
-  const B();
-}
-class C<E1> {
-  void foo<E2>([B<E1, E2> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_methodNG() async {
@@ -5433,10 +5128,9 @@
   void foo([B<T> b = const B()]) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
@@ -5445,18 +5139,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  void foo([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_duplicateDeclaration_class() async {
@@ -6234,8 +5917,7 @@
   const B();
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A<T> {
   const A();
 }
@@ -6247,7 +5929,6 @@
   const B();
 }
 ''');
-    }
   }
 
   test_field_final_hasInitializer_noConstConstructor() async {
@@ -6431,10 +6112,10 @@
         library,
         r'''
 class C1 {
-  final List<int> f1 =
-    ListLiteral
-      isConst: true
-      staticType: List<int>
+  final List<int> f1;
+    constantInitializer
+      ListLiteral
+        staticType: List<int>
   const C1();
 }
 class C2 {
@@ -6832,15 +6513,9 @@
     var library = await checkLibrary('''
 typedef F<X extends F> = Function(F);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 notSimplyBounded typedef F<X> = dynamic Function();
 ''');
-    } else {
-      checkElementText(library, r'''
-notSimplyBounded typedef F<X extends dynamic Function(...)> = dynamic Function(dynamic Function(...) );
-''');
-    }
   }
 
   test_getter_documented() async {
@@ -6894,8 +6569,7 @@
 }
 const x = C.named(42);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   final Object x;
   const C.named(Object this.x);
@@ -6904,17 +6578,6 @@
         C/*location: test.dart;C*/.
         named/*location: test.dart;C;named*/(42);
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  final Object x;
-  const C.named(Object this.x);
-}
-const C x = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(42);
-''');
-    }
   }
 
   test_implicitTopLevelVariable_getterFirst() async {
@@ -8047,19 +7710,11 @@
 import 'c.dart';
 foo([p = V]) {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'c.dart';
 dynamic foo([dynamic p =
         V/*location: a.dart;V*/]) {}
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'c.dart';
-dynamic foo([dynamic p =
-        V/*location: null*/]) {}
-''');
-    }
   }
 
   test_invalid_nameConflict_local() async {
@@ -8068,21 +7723,12 @@
 V() {}
 var V;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 dynamic V;
 dynamic foo([dynamic p =
         V/*location: test.dart;V?*/]) {}
 dynamic V() {}
 ''');
-    } else {
-      checkElementText(library, r'''
-dynamic V;
-dynamic foo([dynamic p =
-        V/*location: null*/]) {}
-dynamic V() {}
-''');
-    }
   }
 
   test_invalid_setterParameter_fieldFormalParameter() async {
@@ -8459,6 +8105,62 @@
 ''');
   }
 
+  test_metadata_class_scope() async {
+    var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+class C<@foo T> {
+  static const foo = 1;
+  @foo
+  void bar() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C {
+  static const int foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 1
+        staticType: int
+  void bar() {}
+    metadata
+      Annotation
+        element: self::C::foo
+        name: SimpleIdentifier
+          staticElement: self::C::foo
+          staticType: int
+          token: foo
+}
+  metadata
+    Annotation
+      element: self::foo
+      name: SimpleIdentifier
+        staticElement: self::foo
+        staticType: int
+        token: foo
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+      metadata
+        Annotation
+          element: self::foo
+          name: SimpleIdentifier
+            staticElement: self::foo
+            staticType: int
+            token: foo
+const int foo;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_classDeclaration() async {
     var library = await checkLibrary(r'''
 const a = null;
@@ -8522,8 +8224,7 @@
 @foo.A.named()
 class C {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'foo.dart' as foo;
 @
         foo/*location: test.dart;foo*/.
@@ -8532,16 +8233,6 @@
 class C {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        A/*location: foo.dart;A*/.
-        named/*location: foo.dart;A;named*/()
-class C {
-}
-''');
-    }
   }
 
   test_metadata_constructor_call_unnamed() async {
@@ -8561,8 +8252,7 @@
     addLibrarySource('/foo.dart', 'class A { const A(); }');
     var library =
         await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'foo.dart' as foo;
 @
         foo/*location: test.dart;foo*/.
@@ -8570,15 +8260,6 @@
 class C {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        A/*location: foo.dart;A*/()
-class C {
-}
-''');
-    }
   }
 
   test_metadata_constructor_call_with_args() async {
@@ -8661,6 +8342,63 @@
 ''');
   }
 
+  test_metadata_extension_scope() async {
+    featureSet = enableExtensionMethods;
+    var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+extension E<@foo T> on int {
+  static const foo = 1;
+  @foo
+  void bar() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+extension E on int {
+  static const int foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 1
+        staticType: int
+  void bar() {}
+    metadata
+      Annotation
+        element: self::E::foo
+        name: SimpleIdentifier
+          staticElement: self::E::foo
+          staticType: int
+          token: foo
+}
+  metadata
+    Annotation
+      element: self::foo
+      name: SimpleIdentifier
+        staticElement: self::foo
+        staticType: int
+        token: foo
+  typeParameters
+    T
+      bound: null
+      defaultType: null
+      metadata
+        Annotation
+          element: self::foo
+          name: SimpleIdentifier
+            staticElement: self::foo
+            staticType: int
+            token: foo
+const int foo;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_extensionDeclaration() async {
     featureSet = enableExtensionMethods;
     var library = await checkLibrary(r'''
@@ -8819,23 +8557,13 @@
 
   test_metadata_invalid_classDeclaration() async {
     var library = await checkLibrary('f(_) {} @f(42) class C {}');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 @
         f/*location: test.dart;f*/(42)
 class C {
 }
 dynamic f(dynamic _) {}
 ''');
-    } else {
-      checkElementText(library, r'''
-@
-        __unresolved__/*location: null*/
-class C {
-}
-dynamic f(dynamic _) {}
-''');
-    }
   }
 
   test_metadata_libraryDirective() async {
@@ -8925,6 +8653,62 @@
 ''');
   }
 
+  test_metadata_mixin_scope() async {
+    var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+mixin M<@foo T> {
+  static const foo = 1;
+  @foo
+  void bar() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+mixin M on Object {
+  static const int foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 1
+        staticType: int
+  void bar() {}
+    metadata
+      Annotation
+        element: self::M::foo
+        name: SimpleIdentifier
+          staticElement: self::M::foo
+          staticType: int
+          token: foo
+}
+  metadata
+    Annotation
+      element: self::foo
+      name: SimpleIdentifier
+        staticElement: self::foo
+        staticType: int
+        token: foo
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+      metadata
+        Annotation
+          element: self::foo
+          name: SimpleIdentifier
+            staticElement: self::foo
+            staticType: int
+            token: foo
+const int foo;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_mixinDeclaration() async {
     var library = await checkLibrary(r'''
 const a = null;
@@ -10107,25 +9891,15 @@
 var a = A(() => b);
 var b = A(() => a);
 ''');
-    if (isAstBasedSummary) {
-      // There is no cycle with `a` and `b`, because `A` is not generic,
-      // so the type of `new A(...)` does not depend on its arguments.
-      checkElementText(library, '''
+    // There is no cycle with `a` and `b`, because `A` is not generic,
+    // so the type of `new A(...)` does not depend on its arguments.
+    checkElementText(library, '''
 class A {
   A(dynamic _);
 }
 A a;
 A b;
 ''');
-    } else {
-      checkElementText(library, '''
-class A {
-  A(dynamic _);
-}
-dynamic a/*error: dependencyCycle*/;
-dynamic b/*error: dependencyCycle*/;
-''');
-    }
   }
 
   test_type_inference_multiplyDefinedElement() async {
@@ -11416,6 +11190,42 @@
 ''');
   }
 
+  test_variableInitializer_contextType_after_astRewrite() async {
+    var library = await checkLibrary(r'''
+class A<T> {
+  const A();
+}
+const A<int> a = A();
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A();
+}
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+const A<int> a;
+  constantInitializer
+    InstanceCreationExpression
+      argumentList: ArgumentList
+      constructorName: ConstructorName
+        type: TypeName
+          name: SimpleIdentifier
+            staticElement: self::A
+            staticType: A<dynamic>
+            token: A
+          type: A<int>
+      staticElement: ConstructorMember
+        base: self::A::•
+        substitution: {T: int}
+      staticType: A<int>
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_variables() async {
     var library = await checkLibrary('int i; int j;');
     checkElementText(library, r'''
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 83e49ed..0fc7bdc 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -54,8 +54,6 @@
 
   set declaredVariables(DeclaredVariables declaredVariables);
 
-  bool get isAstBasedSummary => false;
-
   MemoryResourceProvider get resourceProvider;
 
   void set testFile(String value);
@@ -84,9 +82,6 @@
       <String, UnlinkedUnitBuilder>{};
 
   PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
-
-  @override
-  bool get isAstBasedSummary => false;
 }
 
 /// [SerializedMockSdk] is a singleton class representing the result of
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 2158740..36d5eb0 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -3394,9 +3394,7 @@
   }
 
   test_inferTypesOnGenericInstantiationsInLibraryCycle() async {
-    // Note: this is a regression test for a non-deterministic behavior we used to
-    // have with inference in library cycles. If you see this test flake out,
-    // change `test` to `skip_test` and reopen bug #48.
+    // Note: this is a regression test for bug #48.
     addFile('''
 import 'main.dart';
 abstract class I<E> {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 0a8d7ee..fc52165 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -224,7 +224,7 @@
 class AbstractStrongTest with ResourceProviderMixin {
   bool _checkCalled = true;
 
-  AnalysisDriver _driver = null;
+  AnalysisDriver _driver;
 
   Map<String, List<Folder>> packageMap;
 
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index b881193..e829ba7 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -120,9 +120,6 @@
     } else if (snippet.indexOf(errorRangeStart, rangeEnd) > 0) {
       _reportProblem('More than one error range in example');
     }
-    if (snippet.indexOf('extension') >= 0) {
-      DateTime.now();
-    }
     return _SnippetData(
         snippet.substring(0, rangeStart) +
             snippet.substring(rangeStart + errorRangeStart.length, rangeEnd) +
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 7f51a0d..c5f56bf 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -73,7 +73,7 @@
     List<CodePath> paths = [];
     for (int i = 0; i < documentationPaths.length; i++) {
       String docPath = pathContext.joinAll(documentationPaths[i]);
-      String declPath = null;
+      String declPath;
       if (declarationPaths[i] != null) {
         declPath = pathContext.joinAll(declarationPaths[i]);
       }
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 8e9c085..7e9a695 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -218,6 +218,8 @@
   /// Returns `true` if [element] is a superclass of `List`.
   bool isListSupertype(ClassEntity element);
 
+  InterfaceType getConstantListTypeFor(InterfaceType sourceType);
+
   InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
       {bool hasProtoKey: false, bool onlyStringKeys: false});
 
@@ -1016,6 +1018,12 @@
   }
 
   @override
+  InterfaceType getConstantListTypeFor(InterfaceType sourceType) =>
+      sourceType.treatAsRaw
+          ? _env.getRawType(jsArrayClass)
+          : _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);
+
+  @override
   InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
       {bool hasProtoKey: false, bool onlyStringKeys: false}) {
     ClassEntity classElement = onlyStringKeys
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 47aa5ed..566c2b9 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -87,8 +87,12 @@
     new StringConstantValue(string);
 BoolConstantValue createBool(bool value) => new BoolConstantValue(value);
 NullConstantValue createNull() => new NullConstantValue();
-ListConstantValue createList(InterfaceType type, List<ConstantValue> values) =>
-    new ListConstantValue(type, values);
+
+ListConstantValue createList(CommonElements commonElements,
+    InterfaceType sourceType, List<ConstantValue> values) {
+  InterfaceType type = commonElements.getConstantListTypeFor(sourceType);
+  return ListConstantValue(type, values);
+}
 
 ConstantValue createType(CommonElements commonElements, DartType type) {
   InterfaceType instanceType = commonElements.typeLiteralType;
@@ -174,7 +178,7 @@
   } else {
     keysType = commonElements.listType(sourceType.typeArguments.first);
   }
-  ListConstantValue keysList = new ListConstantValue(keysType, keys);
+  ListConstantValue keysList = createList(commonElements, keysType, keys);
   InterfaceType type = commonElements.getConstantMapTypeFor(sourceType,
       hasProtoKey: hasProtoKey, onlyStringKeys: onlyStringKeys);
   return new JavaScriptMapConstant(
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 61be000..095bec3 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -375,8 +375,8 @@
 
   @override
   ConstantValue evaluate(EvaluationEnvironment environment) {
-    return constant_system.createList(
-        type, values.map((v) => v.evaluate(environment)).toList());
+    return constant_system.createList(environment.commonElements, type,
+        values.map((v) => v.evaluate(environment)).toList());
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 6ff3566..3c39f11 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -353,7 +353,8 @@
 
   @override
   void handleAsExpression(ir.AsExpression node, ir.DartType operandType) {
-    if (typeEnvironment.isSubtypeOf(operandType, node.type)) {
+    if (typeEnvironment.isSubtypeOf(
+        operandType, node.type, ir.SubtypeCheckMode.ignoringNullabilities)) {
       // Skip unneeded casts.
       return;
     }
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 084ffd0..d686190 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -286,7 +286,8 @@
                 getTypeAsInstanceOf(receiverType, superclass));
         ir.DartType setterType =
             receiverSubstitution.substituteType(interfaceTarget.setterType);
-        if (!typeEnvironment.isSubtypeOf(valueType, setterType)) {
+        if (!typeEnvironment.isSubtypeOf(
+            valueType, setterType, ir.SubtypeCheckMode.ignoringNullabilities)) {
           // We need to insert an implicit cast to preserve the invariant that
           // a property set with a known interface target is also statically
           // checked.
@@ -484,7 +485,8 @@
     for (int i = 0; i < node.arguments.positional.length; i++) {
       ir.DartType argumentType = argumentTypes.positional[i];
       ir.DartType parameterType = parameterTypes.positionalParameters[i];
-      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType)) {
+      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
+          ir.SubtypeCheckMode.ignoringNullabilities)) {
         neededPositionalChecks[i] = parameterType;
       }
     }
@@ -497,7 +499,8 @@
       ir.DartType parameterType = parameterTypes.namedParameters
           .singleWhere((namedType) => namedType.name == namedArgument.name)
           .type;
-      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType)) {
+      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
+          ir.SubtypeCheckMode.ignoringNullabilities)) {
         neededNamedChecks[argumentIndex] = parameterType;
       }
     }
@@ -719,7 +722,8 @@
     assert(
         node.promotedType == null ||
             promotedType == typeEnvironment.nullType ||
-            typeEnvironment.isSubtypeOf(promotedType, node.promotedType),
+            typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
+                ir.SubtypeCheckMode.ignoringNullabilities),
         "Unexpected promotion of ${node.variable} in ${node.parent}. "
         "Expected ${node.promotedType}, found $promotedType");
     _expressionTypeCache[node] = promotedType;
@@ -1474,7 +1478,8 @@
       // TODO(johnniwinther): Special-case the `== null` representation to
       // make it faster.
       for (ir.DartType type in falseTypes) {
-        if (typeEnvironment.isSubtypeOf(declaredType, type)) {
+        if (typeEnvironment.isSubtypeOf(
+            declaredType, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
           return typeEnvironment.nullType;
         }
       }
@@ -1484,9 +1489,11 @@
         if (type == typeEnvironment.nullType) {
           return type;
         }
-        if (typeEnvironment.isSubtypeOf(type, candidate)) {
+        if (typeEnvironment.isSubtypeOf(
+            type, candidate, ir.SubtypeCheckMode.ignoringNullabilities)) {
           candidate = type;
-        } else if (!typeEnvironment.isSubtypeOf(candidate, type)) {
+        } else if (!typeEnvironment.isSubtypeOf(
+            candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
           // We cannot promote. No single type is most specific.
           // TODO(johnniwinther): Compute implied types? For instance when the
           // declared type is `Iterable<String>` and tested type is
@@ -1745,9 +1752,11 @@
           // Keep the current candidate.
         } else if (candidate == typeEnvironment.nullType) {
           candidate = type;
-        } else if (typeEnvironment.isSubtypeOf(candidate, type)) {
+        } else if (typeEnvironment.isSubtypeOf(
+            candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
           candidate = type;
-        } else if (!typeEnvironment.isSubtypeOf(type, candidate)) {
+        } else if (!typeEnvironment.isSubtypeOf(
+            type, candidate, ir.SubtypeCheckMode.ignoringNullabilities)) {
           // We cannot promote. No promoted type of one path is a supertype of
           // the promoted type from all other paths.
           // TODO(johnniwinther): Compute a greatest lower bound, instead?
@@ -1872,7 +1881,8 @@
         changed = true;
         Set<ir.DartType> newTypesOfInterest = new Set<ir.DartType>();
         for (ir.DartType typeOfInterest in info.typesOfInterest) {
-          if (typeEnvironment.isSubtypeOf(type, typeOfInterest)) {
+          if (typeEnvironment.isSubtypeOf(type, typeOfInterest,
+              ir.SubtypeCheckMode.ignoringNullabilities)) {
             newTypesOfInterest.add(typeOfInterest);
           }
         }
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index 6c08757..b41805a 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -728,7 +728,8 @@
     }
     DartType type = elementMap.commonElements
         .listType(elementMap.getDartType(node.typeArgument));
-    return constant_system.createList(type, elements);
+    return constant_system.createList(
+        elementMap.commonElements, type, elements);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index b9a78c9..b7dfa1a 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -473,10 +473,7 @@
 
   jsAst.Expression maybeAddListTypeArgumentsNewRti(
       ConstantValue constant, InterfaceType type, jsAst.Expression value) {
-    // List<T> --> JSArray<T>
-    if (type.element != _commonElements.jsArrayClass) {
-      type = InterfaceType(_commonElements.jsArrayClass, type.typeArguments);
-    }
+    assert(type.element == _commonElements.jsArrayClass);
     if (_rtiNeed.classNeedsTypeArguments(type.element)) {
       return new jsAst.Call(
           getHelperProperty(_commonElements.setRuntimeTypeInfo),
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index b6f90d4..13fbaf9 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -35,57 +35,6 @@
 
   InterceptorData get _interceptorData => _closedWorld.interceptorData;
 
-  jsAst.Expression generateClassConstructor(
-      ClassEntity classElement, List<jsAst.Name> fields, bool hasRtiField) {
-    // TODO(sra): Implement placeholders in VariableDeclaration position:
-    //
-    //     String constructorName = namer.getNameOfClass(classElement);
-    //     return js.statement('function #(#) { #; }',
-    //        [ constructorName, fields,
-    //            fields.map(
-    //                (name) => js('this.# = #', [name, name]))]));
-    dynamic typeParameters = const <jsAst.Parameter>[];
-    dynamic typeInits = const <jsAst.Expression>[];
-    if (hasRtiField) {
-      dynamic rtiName = _namer.rtiFieldJsName;
-      typeParameters = rtiName;
-      typeInits = js('this.# = #', [rtiName, rtiName]);
-    }
-    List<jsAst.Parameter> parameters = new List<jsAst.Parameter>.generate(
-        fields.length, (i) => new jsAst.Parameter('t$i'));
-    List<jsAst.Expression> fieldInitializers =
-        new List<jsAst.Expression>.generate(fields.length, (i) {
-      return js('this.# = #', [fields[i], parameters[i]]);
-    });
-    return js('function(#, #) { #; #; this.#();}', [
-      parameters,
-      typeParameters,
-      fieldInitializers,
-      typeInits,
-      _namer.fixedNames.deferredAction
-    ]);
-  }
-
-  jsAst.Expression generateGetter(MemberEntity member, jsAst.Name fieldName) {
-    ClassEntity cls = member.enclosingClass;
-    String receiver =
-        _interceptorData.isInterceptedClass(cls) ? 'receiver' : 'this';
-    List<String> args =
-        _interceptorData.isInterceptedMethod(member) ? ['receiver'] : [];
-    return js('function(#) { return #.# }', [args, receiver, fieldName]);
-  }
-
-  jsAst.Expression generateSetter(MemberEntity member, jsAst.Name fieldName) {
-    ClassEntity cls = member.enclosingClass;
-    String receiver =
-        _interceptorData.isInterceptedClass(cls) ? 'receiver' : 'this';
-    List<String> args =
-        _interceptorData.isInterceptedMethod(member) ? ['receiver'] : [];
-    // TODO(floitsch): remove 'return'?
-    return js(
-        'function(#, v) { return #.# = v; }', [args, receiver, fieldName]);
-  }
-
   /// Documentation wanted -- johnniwinther
   ///
   /// Invariant: [member] must be a declaration element.
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 78da253..4e4571e 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -847,7 +847,8 @@
         if (member.isAbstract) {
           cls = elementMap.elementEnvironment.getSuperClass(cls);
         } else {
-          return member.enclosingClass != commonElements.objectClass;
+          return member.enclosingClass != commonElements.objectClass &&
+              member.enclosingClass != commonElements.jsInterceptorClass;
         }
       }
       return false;
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index f15d5d2..475c993 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -140,12 +140,13 @@
   }[parsedArgs['output-kind']];
 
   final sourcePath = path.canonicalize(path.normalize(parsedArgs.rest[0]));
+  final sourceWithoutDart = sourcePath.replaceFirst(new RegExp(r'\.dart$'), '');
   final outputPath =
       path.canonicalize(path.normalize(parsedArgs['output'] != null
           ? parsedArgs['output']
           : {
-              Kind.aot: '${sourcePath}.aot',
-              Kind.exe: '${sourcePath}.exe',
+              Kind.aot: '${sourceWithoutDart}.aot',
+              Kind.exe: '${sourceWithoutDart}.exe',
             }[kind]));
 
   if (!FileSystemEntity.isFileSync(sourcePath)) {
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 645dd90..4a2f6e6 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -446,10 +446,14 @@
   /// Returns the canonical name to refer to the Dart library.
   @protected
   js_ast.Identifier emitLibraryName(Library library) {
+    // Avoid adding the dart:_runtime to _imports when our runtime unit tests
+    // import it explicitly. It will always be implicitly imported.
+    if (isSdkInternalRuntime(library)) return runtimeModule;
+
     // It's either one of the libraries in this module, or it's an import.
-    var libraryId = js_ast.TemporaryId(jsLibraryName(library));
     return _libraries[library] ??
-        _imports.putIfAbsent(library, () => libraryId);
+        _imports.putIfAbsent(
+            library, () => js_ast.TemporaryId(jsLibraryName(library)));
   }
 
   /// Emits imports and extension methods into [items].
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index c741457..8401522 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -243,6 +243,7 @@
   fe.IncrementalCompiler incrementalCompiler;
   fe.WorkerInputComponent cachedSdkInput;
   bool recordUsedInputs = argResults['used-inputs-file'] != null;
+  List<Uri> inputSummaries = summaryModules.keys.toList();
   if (useAnalyzer || !useIncrementalCompiler) {
     compilerState = await fe.initializeCompiler(
         oldCompilerState,
@@ -251,7 +252,7 @@
         compileSdk ? null : sourcePathToUri(sdkSummaryPath),
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
-        summaryModules.keys.toList(),
+        inputSummaries,
         DevCompilerTarget(
             TargetFlags(trackWidgetCreation: trackWidgetCreation)),
         fileSystem: fileSystem,
@@ -286,7 +287,7 @@
         compileSdk ? null : sourcePathToUri(sdkSummaryPath),
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
-        summaryModules.keys.toList(),
+        inputSummaries,
         inputDigests,
         DevCompilerTarget(
             TargetFlags(trackWidgetCreation: trackWidgetCreation)),
@@ -299,8 +300,6 @@
         compilerState.workerInputCache[sourcePathToUri(sdkSummaryPath)];
   }
 
-  List<Uri> inputSummaries = compilerState.options.inputSummaries;
-
   // TODO(jmesserly): is there a cleaner way to do this?
   //
   // Ideally we'd manage our own batch compilation caching rather than rely on
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 57b2fe0..db30dd1 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5044,7 +5044,10 @@
     //      }
     //
     var isTypeError = node.isTypeError;
-    if (!isTypeError && _types.isSubtypeOf(from, to)) return jsFrom;
+    if (!isTypeError &&
+        _types.isSubtypeOf(from, to, SubtypeCheckMode.ignoringNullabilities)) {
+      return jsFrom;
+    }
 
     // All Dart number types map to a JS double.
     if (_typeRep.isNumber(from) && _typeRep.isNumber(to)) {
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 5ae85a5..3bd4a1f 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -64,7 +64,16 @@
       uri.scheme == 'dart' &&
       (uri.path == 'core' || uri.path == '_interceptors');
 
+  /// Returns [true] if [uri] represents a test script has been whitelisted to
+  /// import private platform libraries.
+  ///
+  /// Unit tests for the dart:_runtime library have imports like this. It is
+  /// only allowed from a specific SDK test directory or through the modular
+  /// test framework.
   bool _allowedTestLibrary(Uri uri) {
+    // Multi-root scheme used by modular test framework.
+    if (uri.scheme == 'dev-dart-app') return true;
+
     String scriptName = uri.path;
     return scriptName.contains('tests/compiler/dartdevc_native');
   }
diff --git a/pkg/dev_compiler/test/modular_ddc_suite.dart b/pkg/dev_compiler/test/modular_ddc_suite.dart
index fac2975..4c2a413 100644
--- a/pkg/dev_compiler/test/modular_ddc_suite.dart
+++ b/pkg/dev_compiler/test/modular_ddc_suite.dart
@@ -36,7 +36,17 @@
       IOPipeline([
         DDCStep(),
         RunD8(),
-      ], cacheSharedModules: true, saveIntermediateResultsForTesting: false));
+      ], cacheSharedModules: true));
+
+  // DDC only test suite.
+  await runSuite(
+      sdkRoot.resolve('tests/compiler/dartdevc/modular/'),
+      'tests/compiler/dartdevc/modular',
+      _options,
+      IOPipeline([
+        DDCStep(),
+        RunD8(),
+      ], cacheSharedModules: true));
 }
 
 const sumId = DataId("sum");
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 2442d93..0b4e1e6 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -81,6 +81,9 @@
       extraArgs = ['--packages-file', '$rootScheme:/.packages'];
     }
 
+    Module sdkModule =
+        module.isSdk ? module : module.dependencies.firstWhere((m) => m.isSdk);
+
     List<String> args = [
       _kernelWorkerScript,
       '--summary-only',
@@ -93,8 +96,14 @@
       ...extraArgs,
       '--output',
       '${toUri(module, dillId)}',
+      if (!module.isSdk) ...[
+        '--dart-sdk-summary',
+        '${toUri(sdkModule, dillId)}',
+        '--exclude-non-sources',
+      ],
       ...(transitiveDependencies
-          .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
+          .where((m) => !m.isSdk)
+          .expand((m) => ['--input-summary', '${toUri(m, dillId)}'])),
       ...(sources.expand((String uri) => ['--source', uri])),
       ...(flags.expand((String flag) => ['--enable-experiment', flag])),
     ];
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 052e2dd..d36bd4a 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -43,7 +43,7 @@
 const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
   ExperimentalFlag.constantUpdate2018: true,
   ExperimentalFlag.controlFlowCollections: true,
-  ExperimentalFlag.extensionMethods: false,
+  ExperimentalFlag.extensionMethods: true,
   ExperimentalFlag.nonNullable: false,
   ExperimentalFlag.setLiterals: true,
   ExperimentalFlag.spreadCollections: true,
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index fd091bb..3618c93 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -26,7 +26,9 @@
   Uri currentDirectory;
 
   MemoryFileSystem(Uri currentDirectory)
-      : currentDirectory = _addTrailingSlash(currentDirectory);
+      : currentDirectory = _addTrailingSlash(currentDirectory) {
+    _directories.add(currentDirectory);
+  }
 
   @override
   MemoryFileSystemEntity entityForUri(Uri uri) {
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 6c6b5a4..57080d9 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -9,7 +9,7 @@
 
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 
-import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+import 'package:kernel/kernel.dart' show Component, Library;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -20,23 +20,27 @@
 
 import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 
-import '../api_prototype/front_end.dart' show CompilerResult;
-
 import '../api_prototype/file_system.dart' show FileSystem;
 
+import '../api_prototype/front_end.dart' show CompilerResult;
+
 import '../base/processed_options.dart' show ProcessedOptions;
 
-import '../fasta/compiler_context.dart' show CompilerContext;
-
-import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
-
 import '../kernel_generator_impl.dart' show generateKernel;
 
-import 'compiler_state.dart'
-    show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+import 'compiler_state.dart' show InitializedCompilerState;
+
+import 'modular_incremental_compilation.dart' as modular
+    show initializeIncrementalCompiler;
+
+export '../api_prototype/compiler_options.dart'
+    show parseExperimentalFlags, parseExperimentalArguments;
 
 export '../api_prototype/diagnostic_message.dart' show DiagnosticMessage;
 
+export '../api_prototype/experimental_flags.dart'
+    show ExperimentalFlag, parseExperimentalFlag;
+
 export '../api_prototype/standard_file_system.dart' show StandardFileSystem;
 
 export '../api_prototype/terminal_color_support.dart'
@@ -48,11 +52,9 @@
 
 export 'compiler_state.dart' show InitializedCompilerState;
 
-import 'util.dart' show equalMaps, equalSets;
-
 /// Initializes the compiler for a modular build.
 ///
-/// Re-uses cached components from [_workerInputCache], and reloads them
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
 /// as necessary based on [workerInputDigests].
 Future<InitializedCompilerState> initializeIncrementalCompiler(
     InitializedCompilerState oldState,
@@ -67,193 +69,26 @@
     Iterable<String> experiments,
     bool outlineOnly,
     {bool trackNeededDillLibraries: false}) async {
-  final List<int> sdkDigest = workerInputDigests[sdkSummary];
-  if (sdkDigest == null) {
-    throw new StateError("Expected to get digest for $sdkSummary");
-  }
-  IncrementalCompiler incrementalCompiler;
-  CompilerOptions options;
-  ProcessedOptions processedOpts;
-  WorkerInputComponent cachedSdkInput;
-  Map<Uri, WorkerInputComponent> workerInputCache =
-      oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
-  Map<Uri, Uri> workerInputCacheLibs =
-      oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
-
-  bool startOver = false;
+  List<Component> outputLoadedInputSummaries =
+      new List<Component>(summaryInputs.length);
   Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
       parseExperimentalArguments(experiments),
       onError: (e) => throw e);
-
-  if (oldState == null ||
-      oldState.incrementalCompiler == null ||
-      oldState.incrementalCompiler.outlineOnly != outlineOnly ||
-      !equalMaps(oldState.options.experimentalFlags, experimentalFlags) ||
-      !equalSets(oldState.tags, tags)) {
-    // No - or immediately not correct - previous state.
-    startOver = true;
-
-    // We'll load a new sdk, anything loaded already will have a wrong root.
-    workerInputCache.clear();
-    workerInputCacheLibs.clear();
-  } else {
-    // We do have a previous state.
-    cachedSdkInput = workerInputCache[sdkSummary];
-    if (cachedSdkInput == null ||
-        !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
-      // The sdk is out of date.
-      startOver = true;
-      // We'll load a new sdk, anything loaded already will have a wrong root.
-      workerInputCache.clear();
-      workerInputCacheLibs.clear();
-    }
-  }
-
-  if (startOver) {
-    // The sdk was either not cached or it has changed.
-    options = new CompilerOptions()
-      ..sdkSummary = sdkSummary
-      ..packagesFileUri = packagesFile
-      ..librariesSpecificationUri = librariesSpecificationUri
-      ..target = target
-      ..fileSystem = fileSystem
-      ..omitPlatform = true
-      ..environmentDefines = const {}
-      ..experimentalFlags = experimentalFlags;
-
-    processedOpts = new ProcessedOptions(options: options);
-    cachedSdkInput = new WorkerInputComponent(
-        sdkDigest, await processedOpts.loadSdkSummary(null));
-    workerInputCache[sdkSummary] = cachedSdkInput;
-    for (Library lib in cachedSdkInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        throw new StateError("Duplicate sources in sdk.");
-      }
-      workerInputCacheLibs[lib.importUri] = sdkSummary;
-    }
-
-    incrementalCompiler = new IncrementalCompiler.fromComponent(
-        new CompilerContext(processedOpts),
-        cachedSdkInput.component,
-        outlineOnly);
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-  } else {
-    options = oldState.options;
-    processedOpts = oldState.processedOpts;
-    Component sdkComponent = cachedSdkInput.component;
-    // Reset the state of the component.
-    for (Library lib in sdkComponent.libraries) {
-      lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
-    }
-
-    // Make sure the canonical name root knows about the sdk - otherwise we
-    // won't be able to link to it when loading more outlines.
-    sdkComponent.adoptChildren();
-
-    // TODO(jensj): This is - at least currently - necessary,
-    // although it's not entirely obvious why.
-    // It likely has to do with several outlines containing the same libraries.
-    // Once that stops (and we check for it) we can probably remove this,
-    // and instead only do it when about to reuse an outline in the
-    // 'inputSummaries.add(component);' line further down.
-    for (WorkerInputComponent cachedInput in workerInputCache.values) {
-      cachedInput.component.adoptChildren();
-    }
-
-    // Reuse the incremental compiler, but reset as needed.
-    incrementalCompiler = oldState.incrementalCompiler;
-    incrementalCompiler.invalidateAllSources();
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-    options.packagesFileUri = packagesFile;
-    options.fileSystem = fileSystem;
-    processedOpts.clearFileSystemCache();
-  }
-
-  // Then read all the input summary components.
-  CanonicalName nameRoot = cachedSdkInput.component.root;
-  final List<Component> inputSummaries = <Component>[];
-  Map<Uri, Uri> libraryToInputDill;
-  if (trackNeededDillLibraries) {
-    libraryToInputDill = new Map<Uri, Uri>();
-  }
-  List<Uri> loadFromDill = new List<Uri>();
-  Set<Uri> inputSummariesSet = new Set<Uri>();
-  for (Uri summary in summaryInputs) {
-    inputSummariesSet.add(summary);
-    WorkerInputComponent cachedInput = workerInputCache[summary];
-    List<int> summaryDigest = workerInputDigests[summary];
-    if (summaryDigest == null) {
-      throw new StateError("Expected to get digest for $summary");
-    }
-    if (cachedInput == null ||
-        cachedInput.component.root != nameRoot ||
-        !digestsEqual(cachedInput.digest, summaryDigest)) {
-      // Remove any old libraries from workerInputCacheLibs.
-      Component component = cachedInput?.component;
-      if (component != null) {
-        for (Library lib in component.libraries) {
-          workerInputCacheLibs.remove(lib.importUri);
-        }
-      }
-
-      loadFromDill.add(summary);
-    } else {
-      // Need to reset cached components so they are usable again.
-      Component component = cachedInput.component;
-      for (Library lib in component.libraries) {
-        lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
-        if (trackNeededDillLibraries) {
-          libraryToInputDill[lib.importUri] = summary;
-        }
-      }
-      inputSummaries.add(component);
-    }
-  }
-
-  for (int i = 0; i < loadFromDill.length; i++) {
-    Uri summary = loadFromDill[i];
-    List<int> summaryDigest = workerInputDigests[summary];
-    if (summaryDigest == null) {
-      throw new StateError("Expected to get digest for $summary");
-    }
-    WorkerInputComponent cachedInput = new WorkerInputComponent(
-        summaryDigest,
-        await processedOpts.loadComponent(
-            await fileSystem.entityForUri(summary).readAsBytes(), nameRoot,
-            alwaysCreateNewNamedNodes: true));
-    workerInputCache[summary] = cachedInput;
-    inputSummaries.add(cachedInput.component);
-    for (Library lib in cachedInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        Uri fromSummary = workerInputCacheLibs[lib.importUri];
-        if (inputSummariesSet.contains(fromSummary)) {
-          throw new StateError(
-              "Asked to load several summaries that contain the same library.");
-        } else {
-          // Library contained in old cached component. Flush that cache.
-          Component component = workerInputCache.remove(fromSummary).component;
-          for (Library lib in component.libraries) {
-            workerInputCacheLibs.remove(lib.importUri);
-          }
-        }
-      } else {
-        workerInputCacheLibs[lib.importUri] = summary;
-      }
-
-      if (trackNeededDillLibraries) {
-        libraryToInputDill[lib.importUri] = summary;
-      }
-    }
-  }
-
-  incrementalCompiler.setModulesToLoadOnNextComputeDelta(inputSummaries);
-
-  return new InitializedCompilerState(options, processedOpts,
-      workerInputCache: workerInputCache,
-      workerInputCacheLibs: workerInputCacheLibs,
-      incrementalCompiler: incrementalCompiler,
-      tags: tags,
-      libraryToInputDill: libraryToInputDill);
+  return modular.initializeIncrementalCompiler(
+      oldState,
+      tags,
+      outputLoadedInputSummaries,
+      sdkSummary,
+      packagesFile,
+      librariesSpecificationUri,
+      summaryInputs,
+      workerInputDigests,
+      target,
+      fileSystem: fileSystem,
+      experimentalFlags: experimentalFlags,
+      outlineOnly: outlineOnly,
+      omitPlatform: true,
+      trackNeededDillLibraries: trackNeededDillLibraries);
 }
 
 Future<InitializedCompilerState> initializeCompiler(
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 8885e67..0a5122b 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -6,7 +6,7 @@
 
 import 'package:kernel/class_hierarchy.dart';
 
-import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+import 'package:kernel/kernel.dart' show Component;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -24,16 +24,14 @@
 
 import '../base/processed_options.dart' show ProcessedOptions;
 
-import '../fasta/compiler_context.dart' show CompilerContext;
-
-import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
-
 import '../kernel_generator_impl.dart' show generateKernel;
 
-import 'compiler_state.dart'
-    show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+import 'compiler_state.dart' show InitializedCompilerState;
 
-import 'util.dart' show equalLists, equalMaps, equalSets;
+import 'modular_incremental_compilation.dart' as modular
+    show initializeIncrementalCompiler;
+
+import 'util.dart' show equalLists, equalMaps;
 
 export '../api_prototype/compiler_options.dart'
     show CompilerOptions, parseExperimentalFlags, parseExperimentalArguments;
@@ -132,6 +130,10 @@
   return new InitializedCompilerState(options, processedOpts);
 }
 
+/// Initializes the compiler for a modular build.
+///
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
+/// as necessary based on [workerInputDigests].
 Future<InitializedCompilerState> initializeIncrementalCompiler(
     InitializedCompilerState oldState,
     Set<String> tags,
@@ -148,183 +150,25 @@
     Map<ExperimentalFlag, bool> experiments,
     Map<String, String> environmentDefines,
     bool trackNeededDillLibraries: false}) async {
-  inputSummaries.sort((a, b) => a.toString().compareTo(b.toString()));
-
-  IncrementalCompiler incrementalCompiler;
-  WorkerInputComponent cachedSdkInput;
-  CompilerOptions options;
-  ProcessedOptions processedOpts;
-
-  Map<Uri, WorkerInputComponent> workerInputCache =
-      oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
-  Map<Uri, Uri> workerInputCacheLibs =
-      oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
-
-  final List<int> sdkDigest = workerInputDigests[sdkSummary];
-  if (sdkDigest == null) {
-    throw new StateError("Expected to get sdk digest at $sdkSummary");
-  }
-
-  cachedSdkInput = workerInputCache[sdkSummary];
-
-  if (oldState == null ||
-      oldState.incrementalCompiler == null ||
-      oldState.options.compileSdk != compileSdk ||
-      cachedSdkInput == null ||
-      !digestsEqual(cachedSdkInput.digest, sdkDigest) ||
-      !equalMaps(oldState.options.experimentalFlags, experiments) ||
-      !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
-      !equalSets(oldState.tags, tags)) {
-    // No - or immediately not correct - previous state.
-    options = new CompilerOptions()
-      ..compileSdk = compileSdk
-      ..sdkRoot = sdkRoot
-      ..sdkSummary = sdkSummary
-      ..packagesFileUri = packagesFile
-      ..inputSummaries = inputSummaries
-      ..librariesSpecificationUri = librariesSpecificationUri
-      ..target = target
-      ..fileSystem = fileSystem ?? StandardFileSystem.instance
-      ..environmentDefines = environmentDefines;
-    if (experiments != null) options.experimentalFlags = experiments;
-
-    // We'll load a new sdk, anything loaded already will have a wrong root.
-    workerInputCache.clear();
-    workerInputCacheLibs.clear();
-
-    processedOpts = new ProcessedOptions(options: options);
-
-    cachedSdkInput = new WorkerInputComponent(
-        sdkDigest, await processedOpts.loadSdkSummary(null));
-    workerInputCache[sdkSummary] = cachedSdkInput;
-    for (Library lib in cachedSdkInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        throw new StateError("Duplicate sources in sdk.");
-      }
-      workerInputCacheLibs[lib.importUri] = sdkSummary;
-    }
-
-    incrementalCompiler = new IncrementalCompiler.fromComponent(
-        new CompilerContext(processedOpts), cachedSdkInput.component);
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-  } else {
-    options = oldState.options;
-    options.inputSummaries = inputSummaries;
-    processedOpts = oldState.processedOpts;
-
-    for (Library lib in cachedSdkInput.component.libraries) {
-      lib.isExternal = false;
-    }
-    cachedSdkInput.component.adoptChildren();
-    for (WorkerInputComponent cachedInput in workerInputCache.values) {
-      cachedInput.component.adoptChildren();
-    }
-
-    // Reuse the incremental compiler, but reset as needed.
-    incrementalCompiler = oldState.incrementalCompiler;
-    incrementalCompiler.invalidateAllSources();
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-    options.packagesFileUri = packagesFile;
-    options.fileSystem = fileSystem;
-    processedOpts.clearFileSystemCache();
-  }
-  InitializedCompilerState compilerState = new InitializedCompilerState(
-      options, processedOpts,
-      workerInputCache: workerInputCache,
-      incrementalCompiler: incrementalCompiler);
-
-  CanonicalName nameRoot = cachedSdkInput.component.root;
-  Map<Uri, Uri> libraryToInputDill;
-  if (trackNeededDillLibraries) {
-    libraryToInputDill = new Map<Uri, Uri>();
-  }
-  List<int> loadFromDillIndexes = new List<int>();
-
-  // Notice that the ordering of the input summaries matter, so we need to
-  // keep them in order.
-  if (doneInputSummaries.length != inputSummaries.length) {
-    throw new ArgumentError("Invalid length.");
-  }
-  Set<Uri> inputSummariesSet = new Set<Uri>();
-  for (int i = 0; i < inputSummaries.length; i++) {
-    Uri inputSummary = inputSummaries[i];
-    inputSummariesSet.add(inputSummary);
-    WorkerInputComponent cachedInput = workerInputCache[inputSummary];
-    List<int> digest = workerInputDigests[inputSummary];
-    if (digest == null) {
-      throw new StateError("Expected to get digest for $inputSummary");
-    }
-    if (cachedInput == null ||
-        cachedInput.component.root != nameRoot ||
-        !digestsEqual(digest, cachedInput.digest)) {
-      // Remove any old libraries from workerInputCacheLibs.
-      Component component = cachedInput?.component;
-      if (component != null) {
-        for (Library lib in component.libraries) {
-          workerInputCacheLibs.remove(lib.importUri);
-        }
-      }
-
-      loadFromDillIndexes.add(i);
-    } else {
-      // Need to reset cached components so they are usable again.
-      Component component = cachedInput.component;
-      for (Library lib in component.libraries) {
-        lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
-        if (trackNeededDillLibraries) {
-          libraryToInputDill[lib.importUri] = inputSummary;
-        }
-      }
-      component.computeCanonicalNames();
-      doneInputSummaries[i] = component;
-    }
-  }
-
-  for (int i = 0; i < loadFromDillIndexes.length; i++) {
-    int index = loadFromDillIndexes[i];
-    Uri summary = inputSummaries[index];
-    List<int> digest = workerInputDigests[summary];
-    if (digest == null) {
-      throw new StateError("Expected to get digest for $summary");
-    }
-    List<int> bytes = await fileSystem.entityForUri(summary).readAsBytes();
-    WorkerInputComponent cachedInput = new WorkerInputComponent(
-        digest,
-        await compilerState.processedOpts
-            .loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
-    workerInputCache[summary] = cachedInput;
-    doneInputSummaries[index] = cachedInput.component;
-    for (Library lib in cachedInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        Uri fromSummary = workerInputCacheLibs[lib.importUri];
-        if (inputSummariesSet.contains(fromSummary)) {
-          throw new StateError(
-              "Asked to load several summaries that contain the same library.");
-        } else {
-          // Library contained in old cached component. Flush that cache.
-          Component component = workerInputCache.remove(fromSummary).component;
-          for (Library lib in component.libraries) {
-            workerInputCacheLibs.remove(lib.importUri);
-          }
-        }
-      } else {
-        workerInputCacheLibs[lib.importUri] = summary;
-      }
-
-      if (trackNeededDillLibraries) {
-        libraryToInputDill[lib.importUri] = summary;
-      }
-    }
-  }
-
-  incrementalCompiler.setModulesToLoadOnNextComputeDelta(doneInputSummaries);
-
-  return new InitializedCompilerState(options, processedOpts,
-      workerInputCache: workerInputCache,
-      workerInputCacheLibs: workerInputCacheLibs,
-      incrementalCompiler: incrementalCompiler,
-      tags: tags,
-      libraryToInputDill: libraryToInputDill);
+  return modular.initializeIncrementalCompiler(
+      oldState,
+      tags,
+      doneInputSummaries,
+      sdkSummary,
+      packagesFile,
+      librariesSpecificationUri,
+      inputSummaries,
+      workerInputDigests,
+      target,
+      compileSdk: compileSdk,
+      sdkRoot: sdkRoot,
+      fileSystem: fileSystem ?? StandardFileSystem.instance,
+      experimentalFlags: experiments,
+      environmentDefines:
+          environmentDefines ?? const <ExperimentalFlag, bool>{},
+      outlineOnly: false,
+      omitPlatform: false,
+      trackNeededDillLibraries: trackNeededDillLibraries);
 }
 
 Future<DdcResult> compile(InitializedCompilerState compilerState,
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
new file mode 100644
index 0000000..5244f74
--- /dev/null
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -0,0 +1,243 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async' show Future;
+
+import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+
+import 'package:kernel/target/targets.dart' show Target;
+
+import '../api_prototype/compiler_options.dart' show CompilerOptions;
+
+import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
+
+import '../api_prototype/file_system.dart' show FileSystem;
+
+import '../base/processed_options.dart' show ProcessedOptions;
+
+import '../fasta/compiler_context.dart' show CompilerContext;
+
+import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
+
+import 'compiler_state.dart'
+    show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+
+import 'util.dart' show equalMaps, equalSets;
+
+/// Initializes the compiler for a modular build.
+///
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
+/// as necessary based on [workerInputDigests].
+///
+/// Notes:
+/// * [outputLoadedInputSummaries] should be given as an empty list of the same
+///   size as the [inputSummaries]. The input summaries are loaded (or taken
+///   from cache) and placed in this list in order, i.e. the `i`-th entry in
+///   [outputLoadedInputSummaries] after this call corresponds to the component
+///   loaded from the `i`-th entry in [inputSummaries].
+Future<InitializedCompilerState> initializeIncrementalCompiler(
+    InitializedCompilerState oldState,
+    Set<String> tags,
+    List<Component> outputLoadedInputSummaries,
+    Uri sdkSummary,
+    Uri packagesFile,
+    Uri librariesSpecificationUri,
+    List<Uri> inputSummaries,
+    Map<Uri, List<int>> workerInputDigests,
+    Target target,
+    {bool compileSdk: false,
+    Uri sdkRoot: null,
+    FileSystem fileSystem,
+    Map<ExperimentalFlag, bool> experimentalFlags,
+    Map<String, String> environmentDefines: const {},
+    bool outlineOnly,
+    bool omitPlatform: false,
+    bool trackNeededDillLibraries: false}) async {
+  final List<int> sdkDigest = workerInputDigests[sdkSummary];
+  if (sdkDigest == null) {
+    throw new StateError("Expected to get digest for $sdkSummary");
+  }
+
+  Map<Uri, WorkerInputComponent> workerInputCache =
+      oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+  Map<Uri, Uri> workerInputCacheLibs =
+      oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
+
+  WorkerInputComponent cachedSdkInput = workerInputCache[sdkSummary];
+
+  IncrementalCompiler incrementalCompiler;
+  CompilerOptions options;
+  ProcessedOptions processedOpts;
+
+  if (oldState == null ||
+      oldState.incrementalCompiler == null ||
+      oldState.options.compileSdk != compileSdk ||
+      oldState.incrementalCompiler.outlineOnly != outlineOnly ||
+      !equalMaps(oldState.options.experimentalFlags, experimentalFlags) ||
+      !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
+      !equalSets(oldState.tags, tags) ||
+      cachedSdkInput == null ||
+      !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
+    // No - or immediately not correct - previous state.
+    // We'll load a new sdk, anything loaded already will have a wrong root.
+    workerInputCache.clear();
+    workerInputCacheLibs.clear();
+
+    // The sdk was either not cached or it has changed.
+    options = new CompilerOptions()
+      ..compileSdk = compileSdk
+      ..sdkRoot = sdkRoot
+      ..sdkSummary = sdkSummary
+      ..packagesFileUri = packagesFile
+      ..librariesSpecificationUri = librariesSpecificationUri
+      ..target = target
+      ..fileSystem = fileSystem
+      ..omitPlatform = omitPlatform
+      ..environmentDefines = environmentDefines
+      ..experimentalFlags = experimentalFlags;
+
+    processedOpts = new ProcessedOptions(options: options);
+    cachedSdkInput = new WorkerInputComponent(
+        sdkDigest, await processedOpts.loadSdkSummary(null));
+    workerInputCache[sdkSummary] = cachedSdkInput;
+    for (Library lib in cachedSdkInput.component.libraries) {
+      if (workerInputCacheLibs.containsKey(lib.importUri)) {
+        throw new StateError("Duplicate sources in sdk.");
+      }
+      workerInputCacheLibs[lib.importUri] = sdkSummary;
+    }
+
+    incrementalCompiler = new IncrementalCompiler.fromComponent(
+        new CompilerContext(processedOpts),
+        cachedSdkInput.component,
+        outlineOnly);
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
+  } else {
+    options = oldState.options;
+    processedOpts = oldState.processedOpts;
+    Component sdkComponent = cachedSdkInput.component;
+    // Reset the state of the component.
+    for (Library lib in sdkComponent.libraries) {
+      lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
+    }
+
+    // Make sure the canonical name root knows about the sdk - otherwise we
+    // won't be able to link to it when loading more outlines.
+    sdkComponent.adoptChildren();
+
+    // TODO(jensj): This is - at least currently - necessary,
+    // although it's not entirely obvious why.
+    // It likely has to do with several outlines containing the same libraries.
+    // Once that stops (and we check for it) we can probably remove this,
+    // and instead only do it when about to reuse an outline in the
+    // 'inputSummaries.add(component);' line further down.
+    for (WorkerInputComponent cachedInput in workerInputCache.values) {
+      cachedInput.component.adoptChildren();
+    }
+
+    // Reuse the incremental compiler, but reset as needed.
+    incrementalCompiler = oldState.incrementalCompiler;
+    incrementalCompiler.invalidateAllSources();
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
+    options.packagesFileUri = packagesFile;
+    options.fileSystem = fileSystem;
+    processedOpts.clearFileSystemCache();
+  }
+
+  // Then read all the input summary components.
+  CanonicalName nameRoot = cachedSdkInput.component.root;
+  Map<Uri, Uri> libraryToInputDill;
+  if (trackNeededDillLibraries) {
+    libraryToInputDill = new Map<Uri, Uri>();
+  }
+  List<int> loadFromDillIndexes = new List<int>();
+
+  // Notice that the ordering of the input summaries matter, so we need to
+  // keep them in order.
+  if (outputLoadedInputSummaries.length != inputSummaries.length) {
+    throw new ArgumentError("Invalid length.");
+  }
+  Set<Uri> inputSummariesSet = new Set<Uri>();
+  for (int i = 0; i < inputSummaries.length; i++) {
+    Uri summaryUri = inputSummaries[i];
+    inputSummariesSet.add(summaryUri);
+    WorkerInputComponent cachedInput = workerInputCache[summaryUri];
+    List<int> digest = workerInputDigests[summaryUri];
+    if (digest == null) {
+      throw new StateError("Expected to get digest for $summaryUri");
+    }
+    if (cachedInput == null ||
+        cachedInput.component.root != nameRoot ||
+        !digestsEqual(digest, cachedInput.digest)) {
+      // Remove any old libraries from workerInputCacheLibs.
+      Component component = cachedInput?.component;
+      if (component != null) {
+        for (Library lib in component.libraries) {
+          workerInputCacheLibs.remove(lib.importUri);
+        }
+      }
+
+      loadFromDillIndexes.add(i);
+    } else {
+      // Need to reset cached components so they are usable again.
+      Component component = cachedInput.component;
+      for (Library lib in component.libraries) {
+        lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
+        if (trackNeededDillLibraries) {
+          libraryToInputDill[lib.importUri] = summaryUri;
+        }
+      }
+      component.computeCanonicalNames(); // this isn't needed, is it?
+      outputLoadedInputSummaries[i] = component;
+    }
+  }
+
+  for (int i = 0; i < loadFromDillIndexes.length; i++) {
+    int index = loadFromDillIndexes[i];
+    Uri summaryUri = inputSummaries[index];
+    List<int> digest = workerInputDigests[summaryUri];
+    if (digest == null) {
+      throw new StateError("Expected to get digest for $summaryUri");
+    }
+
+    List<int> bytes = await fileSystem.entityForUri(summaryUri).readAsBytes();
+    WorkerInputComponent cachedInput = new WorkerInputComponent(
+        digest,
+        await processedOpts.loadComponent(bytes, nameRoot,
+            alwaysCreateNewNamedNodes: true));
+    workerInputCache[summaryUri] = cachedInput;
+    outputLoadedInputSummaries[index] = cachedInput.component;
+    for (Library lib in cachedInput.component.libraries) {
+      if (workerInputCacheLibs.containsKey(lib.importUri)) {
+        Uri fromSummary = workerInputCacheLibs[lib.importUri];
+        if (inputSummariesSet.contains(fromSummary)) {
+          throw new StateError(
+              "Asked to load several summaries that contain the same library.");
+        } else {
+          // Library contained in old cached component. Flush that cache.
+          Component component = workerInputCache.remove(fromSummary).component;
+          for (Library lib in component.libraries) {
+            workerInputCacheLibs.remove(lib.importUri);
+          }
+        }
+      } else {
+        workerInputCacheLibs[lib.importUri] = summaryUri;
+      }
+
+      if (trackNeededDillLibraries) {
+        libraryToInputDill[lib.importUri] = summaryUri;
+      }
+    }
+  }
+
+  incrementalCompiler
+      .setModulesToLoadOnNextComputeDelta(outputLoadedInputSummaries);
+
+  return new InitializedCompilerState(options, processedOpts,
+      workerInputCache: workerInputCache,
+      workerInputCacheLibs: workerInputCacheLibs,
+      incrementalCompiler: incrementalCompiler,
+      tags: tags,
+      libraryToInputDill: libraryToInputDill);
+}
diff --git a/pkg/front_end/lib/src/base/common.dart b/pkg/front_end/lib/src/base/common.dart
new file mode 100644
index 0000000..e511a04
--- /dev/null
+++ b/pkg/front_end/lib/src/base/common.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// If `true`, data that would not otherwise be kept is stored for testing.
+bool retainDataForTesting = false;
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index c4a1632..ee0b627 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -51,7 +51,10 @@
 import 'package:kernel/type_algebra.dart' as type_algebra
     show getSubstitutionMap;
 
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+    show SubtypeCheckMode, TypeEnvironment;
+
+import '../../base/common.dart';
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
@@ -166,6 +169,8 @@
 
   ClassBuilder actualOrigin;
 
+  ClassBuilder patchForTesting;
+
   ClassBuilder(
       List<MetadataBuilder> metadata,
       int modifiers,
@@ -1165,9 +1170,12 @@
     DartType subtype = inParameter ? interfaceType : declaredType;
     DartType supertype = inParameter ? declaredType : interfaceType;
 
-    if (types.isSubtypeOfKernel(subtype, supertype)) {
+    if (types.isSubtypeOfKernel(
+        subtype, supertype, SubtypeCheckMode.ignoringNullabilities)) {
       // No problem--the proper subtyping relation is satisfied.
-    } else if (isCovariant && types.isSubtypeOfKernel(supertype, subtype)) {
+    } else if (isCovariant &&
+        types.isSubtypeOfKernel(
+            supertype, subtype, SubtypeCheckMode.ignoringNullabilities)) {
       // No problem--the overriding parameter is marked "covariant" and has
       // a type which is a subtype of the parameter it overrides.
     } else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1523,6 +1531,9 @@
   void applyPatch(Builder patch) {
     if (patch is ClassBuilder) {
       patch.actualOrigin = this;
+      if (retainDataForTesting) {
+        patchForTesting = patch;
+      }
       // TODO(ahe): Complain if `patch.supertype` isn't null.
       scope.local.forEach((String name, Builder member) {
         Builder memberPatch = patch.scope.local[name];
@@ -1627,7 +1638,8 @@
         DartType typeArgument = typeArguments[i];
         // Check whether the [typeArgument] respects the bounds of
         // [typeParameter].
-        if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound)) {
+        if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
+            SubtypeCheckMode.ignoringNullabilities)) {
           addProblem(
               templateRedirectingFactoryIncompatibleTypeArgument.withArguments(
                   typeArgument, typeParameterBound),
@@ -1685,7 +1697,8 @@
     if (redirecteeType == null) return;
 
     // Check whether [redirecteeType] <: [factoryType].
-    if (!typeEnvironment.isSubtypeOf(redirecteeType, factoryType)) {
+    if (!typeEnvironment.isSubtypeOf(
+        redirecteeType, factoryType, SubtypeCheckMode.ignoringNullabilities)) {
       addProblem(
           templateIncompatibleRedirecteeFunctionType.withArguments(
               redirecteeType, factoryType),
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index f591207..2f1777b 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -156,4 +156,10 @@
     newTypes.add(newType);
     return newType;
   }
+
+  FunctionTypeBuilder withNullabilityBuilder(
+      NullabilityBuilder nullabilityBuilder) {
+    return new FunctionTypeBuilder(
+        returnType, typeVariables, formals, nullabilityBuilder);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
index a0f7861..2ecb4a6 100644
--- a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
@@ -4,7 +4,8 @@
 
 library fasta.mixin_application_builder;
 
-import 'builder.dart' show LibraryBuilder, TypeBuilder, TypeVariableBuilder;
+import 'builder.dart'
+    show LibraryBuilder, NullabilityBuilder, TypeBuilder, TypeVariableBuilder;
 
 import 'package:kernel/ast.dart' show InterfaceType, Supertype;
 
@@ -23,6 +24,10 @@
 
   String get name => null;
 
+  NullabilityBuilder get nullabilityBuilder {
+    return unsupported("nullabilityBuilder", -1, null);
+  }
+
   String get debugName => "MixinApplicationBuilder";
 
   StringBuffer printOn(StringBuffer buffer) {
@@ -61,6 +66,12 @@
     return unsupported("buildInvalidType", message.charOffset, message.uri);
   }
 
+  @override
+  MixinApplicationBuilder withNullabilityBuilder(
+      NullabilityBuilder nullabilityBuilder) {
+    return unsupported("withNullabilityBuilder", -1, null);
+  }
+
   MixinApplicationBuilder clone(List<TypeBuilder> newTypes) {
     int charOffset = -1; // TODO(dmitryas): Provide these.
     Uri fileUri = null; // TODO(dmitryas): Provide these.
diff --git a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
index 6357975..592ecf2 100644
--- a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
@@ -74,5 +74,6 @@
     return buffer..write(name ?? fullNameForErrors);
   }
 
-  String toString() => "$debugName(${printOn(new StringBuffer())})";
+  String toString() =>
+      "${isPatch ? 'patch ' : ''}$debugName(${printOn(new StringBuffer())})";
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 38a57ae..a956d76 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -296,4 +296,10 @@
     newTypes.add(newType);
     return newType;
   }
+
+  NamedTypeBuilder withNullabilityBuilder(
+      NullabilityBuilder nullabilityBuilder) {
+    return new NamedTypeBuilder(name, nullabilityBuilder, arguments)
+      ..bind(declaration);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index d818e4d..0335f23 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -11,6 +11,8 @@
 
 import 'package:kernel/type_algebra.dart';
 
+import '../../base/common.dart';
+
 import 'builder.dart'
     show
         Builder,
@@ -459,6 +461,7 @@
   final Procedure _procedure;
   final int charOpenParenOffset;
   final ProcedureKind kind;
+  ProcedureBuilder patchForTesting;
 
   AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
 
@@ -553,8 +556,8 @@
       _procedure.isConst = isConst;
       if (isExtensionMethod) {
         ExtensionBuilder extensionBuilder = parent;
-        procedure.isExtensionMember = true;
-        procedure.isStatic = true;
+        _procedure.isExtensionMember = true;
+        _procedure.isStatic = true;
         String kindInfix = '';
         if (isExtensionInstanceMember) {
           // Instance getter and setter are converted to methods so we use an
@@ -574,18 +577,18 @@
               throw new UnsupportedError(
                   'Unexpected extension method kind ${kind}');
           }
-          procedure.kind = ProcedureKind.Method;
+          _procedure.kind = ProcedureKind.Method;
         }
-        procedure.name = new Name(
+        _procedure.name = new Name(
             '${extensionBuilder.name}|${kindInfix}${name}',
             libraryBuilder.library);
       } else {
         _procedure.isStatic = isStatic;
         _procedure.name = new Name(name, libraryBuilder.library);
       }
-    }
-    if (extensionTearOff != null) {
-      _buildExtensionTearOff(libraryBuilder, parent);
+      if (extensionTearOff != null) {
+        _buildExtensionTearOff(libraryBuilder, parent);
+      }
     }
     return _procedure;
   }
@@ -698,7 +701,7 @@
 
     Statement closureBody = new ReturnStatement(
         new StaticInvocation(
-            procedure,
+            _procedure,
             new Arguments(closurePositionalArguments,
                 types: typeArguments, named: closureNamedArguments))
           ..fileOffset = fileOffset)
@@ -709,10 +712,10 @@
         typeParameters: closureTypeParameters,
         positionalParameters: closurePositionalParameters,
         namedParameters: closureNamedParameters,
-        requiredParameterCount: procedure.function.requiredParameterCount - 1,
+        requiredParameterCount: _procedure.function.requiredParameterCount - 1,
         returnType: closureReturnType,
-        asyncMarker: procedure.function.asyncMarker,
-        dartAsyncMarker: procedure.function.dartAsyncMarker))
+        asyncMarker: _procedure.function.asyncMarker,
+        dartAsyncMarker: _procedure.function.dartAsyncMarker))
       ..fileOffset = fileOffset;
 
     _extensionTearOff
@@ -783,6 +786,9 @@
     if (patch is ProcedureBuilder) {
       if (checkPatch(patch)) {
         patch.actualOrigin = this;
+        if (retainDataForTesting) {
+          patchForTesting = patch;
+        }
       }
     } else {
       reportPatchMismatch(patch);
@@ -807,6 +813,8 @@
   @override
   ConstructorBuilder actualOrigin;
 
+  ConstructorBuilder patchForTesting;
+
   Constructor get actualConstructor => _constructor;
 
   ConstructorBuilder(
@@ -998,6 +1006,9 @@
     if (patch is ConstructorBuilder) {
       if (checkPatch(patch)) {
         patch.actualOrigin = this;
+        if (retainDataForTesting) {
+          patchForTesting = patch;
+        }
       }
     } else {
       reportPatchMismatch(patch);
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index f07de9d..7a7bc4c 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -150,10 +150,9 @@
   /// [arguments] have already been built.
   DartType buildTypesWithBuiltArguments(LibraryBuilder library,
       Nullability nullability, List<DartType> arguments) {
-    // TODO(dmitryas): Use [nullability].
     DartType thisType = buildThisType(library);
     if (const DynamicType() == thisType) return thisType;
-    FunctionType result = thisType;
+    FunctionType result = thisType.withNullability(nullability);
     if (typedef.typeParameters.isEmpty && arguments == null) return result;
     Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
     for (int i = 0; i < typedef.typeParameters.length; i++) {
@@ -209,8 +208,9 @@
       NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
     DartType thisType = buildThisType(library);
     if (thisType is InvalidType) return thisType;
-    FunctionType result = thisType;
-    if (typedef.typeParameters.isEmpty && arguments == null) return result;
+    if (typedef.typeParameters.isEmpty && arguments == null) {
+      return thisType.withNullability(nullabilityBuilder.build(library));
+    }
     // Otherwise, substitute.
     return buildTypesWithBuiltArguments(
         library,
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index 93b1ade..ae2428b 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -10,6 +10,7 @@
 
 import '../scope.dart';
 import 'library_builder.dart';
+import 'nullability_builder.dart';
 import 'type_declaration_builder.dart';
 import 'type_variable_builder.dart';
 
@@ -32,6 +33,8 @@
   /// May return null, for example, for mixin applications.
   Object get name;
 
+  NullabilityBuilder get nullabilityBuilder;
+
   String get debugName;
 
   StringBuffer printOn(StringBuffer buffer);
@@ -65,4 +68,6 @@
 
   Supertype buildMixedInType(
       LibraryBuilder library, int charOffset, Uri fileUri);
+
+  TypeBuilder withNullabilityBuilder(NullabilityBuilder nullabilityBuilder);
 }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
index b46cd36..d45a8c7 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
@@ -26,7 +26,7 @@
   bool get isStatic => _descriptor.isStatic;
 
   @override
-  bool get isExternal => _descriptor.isExternal;
+  bool get isExternal => member.isExternal;
 
   @override
   Procedure get procedure {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index ad6ebd4..34eb285 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -161,12 +161,9 @@
         DartType _type,
         DartType
             _type2)> templateArgumentTypeNotAssignable = const Template<
-        Message Function(DartType _type,
-            DartType _type2)>(
+        Message Function(DartType _type, DartType _type2)>(
     messageTemplate:
         r"""The argument type '#type' can't be assigned to the parameter type '#type2'.""",
-    tipTemplate:
-        r"""Try changing the type of the parameter, or casting the argument to '#type2'.""",
     withArguments: _withArgumentsArgumentTypeNotAssignable);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -188,7 +185,6 @@
       message:
           """The argument type '${type}' can't be assigned to the parameter type '${type2}'.""" +
               labeler.originMessages,
-      tip: """Try changing the type of the parameter, or casting the argument to '${type2}'.""",
       arguments: {'type': _type, 'type2': _type2});
 }
 
@@ -422,7 +418,6 @@
     const Template<Message Function(Token token)>(
         messageTemplate:
             r"""The built-in identifier '#lexeme' can't be used as a type.""",
-        tipTemplate: r"""Try correcting the name to match an existing type.""",
         withArguments: _withArgumentsBuiltInIdentifierAsType);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -437,7 +432,6 @@
   return new Message(codeBuiltInIdentifierAsType,
       message:
           """The built-in identifier '${lexeme}' can't be used as a type.""",
-      tip: """Try correcting the name to match an existing type.""",
       arguments: {'token': token});
 }
 
@@ -770,7 +764,7 @@
     "CantUsePrefixWithNullAware",
     analyzerCodes: <String>["PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT"],
     message: r"""A prefix can't be used with null-aware operators.""",
-    tip: r"""It should be safe to remove the '?' as a prefix is never null.""");
+    tip: r"""Try replacing '?.' with '.'""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeCatchSyntax = messageCatchSyntax;
@@ -1771,7 +1765,7 @@
         Message Function(String name)>(
     messageTemplate: r"""The const variable '#name' must be initialized.""",
     tipTemplate:
-        r"""Try adding an initializer ('= <expression>') to the declaration.""",
+        r"""Try adding an initializer ('= expression') to the declaration.""",
     withArguments: _withArgumentsConstFieldWithoutInitializer);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1786,8 +1780,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeConstFieldWithoutInitializer,
       message: """The const variable '${name}' must be initialized.""",
-      tip:
-          """Try adding an initializer ('= <expression>') to the declaration.""",
+      tip: """Try adding an initializer ('= expression') to the declaration.""",
       arguments: {'name': name});
 }
 
@@ -2909,8 +2902,8 @@
     "EqualityCannotBeEqualityOperand",
     index: 1,
     message:
-        r"""An equality expression can't be an operand of another equality expression.""",
-    tip: r"""Try re-writing the expression.""");
+        r"""A comparison expression can't be an operand of another comparison expression.""",
+    tip: r"""Try putting parentheses around one of the comparisons.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string)> templateExpectedAfterButGot =
@@ -3469,6 +3462,32 @@
     tip: r"""Try removing the field declaration or making it a static field""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateExtensionMemberConflictsWithObjectMember =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""This extension member conflicts with Object member '#name'.""",
+        withArguments: _withArgumentsExtensionMemberConflictsWithObjectMember);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeExtensionMemberConflictsWithObjectMember =
+    const Code<Message Function(String name)>(
+  "ExtensionMemberConflictsWithObjectMember",
+  templateExtensionMemberConflictsWithObjectMember,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsExtensionMemberConflictsWithObjectMember(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeExtensionMemberConflictsWithObjectMember,
+      message:
+          """This extension member conflicts with Object member '${name}'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeExternalClass = messageExternalClass;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3539,7 +3558,8 @@
 const MessageCode messageExternalField = const MessageCode("ExternalField",
     index: 50,
     message: r"""Fields can't be declared to be 'external'.""",
-    tip: r"""Try removing the keyword 'external'.""");
+    tip:
+        r"""Try removing the keyword 'external', or replacing the field by an external getter and/or setter.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeExternalMethodWithBody = messageExternalMethodWithBody;
@@ -4103,7 +4123,7 @@
 const MessageCode messageFieldInitializedOutsideDeclaringClass = const MessageCode(
     "FieldInitializedOutsideDeclaringClass",
     index: 88,
-    message: r"""A field can only be initialized in it's declaring class""",
+    message: r"""A field can only be initialized in its declaring class""",
     tip:
         r"""Try passing a value into the superclass constructor, or moving the initialization into the constructor body.""");
 
@@ -4206,7 +4226,7 @@
         Message Function(String name)>(
     messageTemplate: r"""The final variable '#name' must be initialized.""",
     tipTemplate:
-        r"""Try adding an initializer ('= <expression>') to the declaration.""",
+        r"""Try adding an initializer ('= expression') to the declaration.""",
     withArguments: _withArgumentsFinalFieldWithoutInitializer);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4221,8 +4241,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeFinalFieldWithoutInitializer,
       message: """The final variable '${name}' must be initialized.""",
-      tip:
-          """Try adding an initializer ('= <expression>') to the declaration.""",
+      tip: """Try adding an initializer ('= expression') to the declaration.""",
       arguments: {'name': name});
 }
 
@@ -4423,7 +4442,7 @@
     templateGenericFunctionTypeInferredAsActualTypeArgument =
     const Template<Message Function(DartType _type)>(
         messageTemplate:
-            r"""Unexpected generic function type '#type' inferred as a type argument.""",
+            r"""Generic function type '#type' inferred as a type argument.""",
         tipTemplate:
             r"""Try providing a non-generic function type explicitly.""",
         withArguments:
@@ -4445,7 +4464,7 @@
   String type = typeParts.join();
   return new Message(codeGenericFunctionTypeInferredAsActualTypeArgument,
       message:
-          """Unexpected generic function type '${type}' inferred as a type argument.""" +
+          """Generic function type '${type}' inferred as a type argument.""" +
               labeler.originMessages,
       tip: """Try providing a non-generic function type explicitly.""",
       arguments: {'type': _type});
@@ -4460,7 +4479,7 @@
     const MessageCode("GenericFunctionTypeUsedAsActualTypeArgument",
         analyzerCodes: <String>["GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT"],
         message:
-            r"""Unexpected generic function type found in a type argument.""",
+            r"""A generic function type can't be used as a type argument.""",
         tip: r"""Try using a non-generic function type.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6145,8 +6164,6 @@
         Message Function(DartType _type, DartType _type2)>(
     messageTemplate:
         r"""A value of type '#type' can't be assigned to a variable of type '#type2'.""",
-    tipTemplate:
-        r"""Try changing the type of the left hand side, or casting the right hand side to '#type2'.""",
     withArguments: _withArgumentsInvalidAssignment);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6167,7 +6184,6 @@
       message:
           """A value of type '${type}' can't be assigned to a variable of type '${type2}'.""" +
               labeler.originMessages,
-      tip: """Try changing the type of the left hand side, or casting the right hand side to '${type2}'.""",
       arguments: {'type': _type, 'type2': _type2});
 }
 
@@ -6659,8 +6675,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageInvalidVoid = const MessageCode("InvalidVoid",
     analyzerCodes: <String>["EXPECTED_TYPE_NAME"],
-    message:
-        r"""Type 'void' can't be used here because it isn't a return type.""",
+    message: r"""Type 'void' can't be used here.""",
     tip:
         r"""Try removing 'void' keyword or replace it with 'var', 'final', or a type.""");
 
@@ -6935,7 +6950,7 @@
 const MessageCode messageMissingAssignableSelector = const MessageCode(
     "MissingAssignableSelector",
     index: 35,
-    message: r"""Missing selector such as '.<identifier>' or '[0]'.""",
+    message: r"""Missing selector such as '.identifier' or '[0]'.""",
     tip: r"""Try adding a selector.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7162,7 +7177,7 @@
     "MissingPrefixInDeferredImport",
     index: 30,
     message: r"""Deferred imports should have a prefix.""",
-    tip: r"""Try adding a prefix to the import.""");
+    tip: r"""Try adding a prefix to the import by adding an 'as' clause.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMissingTypedefParameters = messageMissingTypedefParameters;
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 43af7e5..61e208b 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -9,11 +9,9 @@
 import 'package:front_end/src/fasta/dill/dill_class_builder.dart'
     show DillClassBuilder;
 
-import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
-
 import 'package:kernel/binary/ast_from_binary.dart'
     show
-        BinaryBuilder,
+        BinaryBuilderWithMetadata,
         CanonicalNameError,
         CanonicalNameSdkError,
         InvalidKernelVersionError;
@@ -730,7 +728,7 @@
     if (summaryBytes != null) {
       ticker.logMs("Read ${c.options.sdkSummary}");
       data.component = c.options.target.configureComponent(new Component());
-      new BinaryBuilder(summaryBytes,
+      new BinaryBuilderWithMetadata(summaryBytes,
               disableLazyReading: false, disableLazyClassReading: true)
           .readComponent(data.component);
       ticker.logMs("Deserialized ${c.options.sdkSummary}");
@@ -755,7 +753,8 @@
 
         // We're going to output all we read here so lazy loading it
         // doesn't make sense.
-        new BinaryBuilder(initializationBytes, disableLazyReading: true)
+        new BinaryBuilderWithMetadata(initializationBytes,
+                disableLazyReading: true)
             .readComponent(data.component, checkCanonicalNames: true);
 
         // Check the any package-urls still point to the same file
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 656b1ae..6d6ca44 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -7,6 +7,7 @@
 import 'dart:core' hide MapEntry;
 
 import 'package:kernel/ast.dart';
+import 'package:kernel/type_environment.dart';
 
 import '../builder/declaration_builder.dart';
 
@@ -826,59 +827,9 @@
           body, transformSetLiterals, transformCollections);
     }
 
-    // For async, async*, and sync* functions with declared return types, we
-    // need to determine whether those types are valid.
     if (builder.returnType != null) {
-      DartType returnType = builder.function.returnType;
-      // We use the same trick in each case below. For example to decide whether
-      // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
-      // transitivity of the subtyping relation because Future<Bot> <: Future<T>
-      // for every T.
-
-      // We use [problem == null] to signal success.
-      Message problem;
-      switch (asyncModifier) {
-        case AsyncMarker.Async:
-          DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
-          if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType)) {
-            problem = fasta.messageIllegalAsyncReturnType;
-          }
-          break;
-
-        case AsyncMarker.AsyncStar:
-          DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
-          if (returnType is VoidType) {
-            problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
-          } else if (!typeEnvironment.isSubtypeOf(
-              streamBottomType, returnType)) {
-            problem = fasta.messageIllegalAsyncGeneratorReturnType;
-          }
-          break;
-
-        case AsyncMarker.SyncStar:
-          DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
-          if (returnType is VoidType) {
-            problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
-          } else if (!typeEnvironment.isSubtypeOf(
-              iterableBottomType, returnType)) {
-            problem = fasta.messageIllegalSyncGeneratorReturnType;
-          }
-          break;
-
-        case AsyncMarker.Sync:
-          break; // skip
-        case AsyncMarker.SyncYielding:
-          unexpected("async, async*, sync, or sync*", "$asyncModifier",
-              member.charOffset, uri);
-          break;
-      }
-
-      if (problem != null) {
-        // TODO(hillerstrom): once types get annotated with location
-        // information, we can improve the quality of the error message by
-        // using the offset of [returnType] (and the length of its name).
-        addProblem(problem, member.charOffset, member.name.length);
-      }
+      checkAsyncReturnType(asyncModifier, builder.function.returnType,
+          member.charOffset, member.name.length);
     }
 
     if (builder.kind == ProcedureKind.Setter) {
@@ -947,6 +898,62 @@
     finishVariableMetadata();
   }
 
+  void checkAsyncReturnType(AsyncMarker asyncModifier, DartType returnType,
+      int charOffset, int length) {
+    // For async, async*, and sync* functions with declared return types, we
+    // need to determine whether those types are valid.
+    // We use the same trick in each case below. For example to decide whether
+    // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
+    // transitivity of the subtyping relation because Future<Bot> <: Future<T>
+    // for every T.
+
+    // We use [problem == null] to signal success.
+    Message problem;
+    switch (asyncModifier) {
+      case AsyncMarker.Async:
+        DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
+        if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType,
+            SubtypeCheckMode.ignoringNullabilities)) {
+          problem = fasta.messageIllegalAsyncReturnType;
+        }
+        break;
+
+      case AsyncMarker.AsyncStar:
+        DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
+        if (returnType is VoidType) {
+          problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
+        } else if (!typeEnvironment.isSubtypeOf(streamBottomType, returnType,
+            SubtypeCheckMode.ignoringNullabilities)) {
+          problem = fasta.messageIllegalAsyncGeneratorReturnType;
+        }
+        break;
+
+      case AsyncMarker.SyncStar:
+        DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
+        if (returnType is VoidType) {
+          problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
+        } else if (!typeEnvironment.isSubtypeOf(iterableBottomType, returnType,
+            SubtypeCheckMode.ignoringNullabilities)) {
+          problem = fasta.messageIllegalSyncGeneratorReturnType;
+        }
+        break;
+
+      case AsyncMarker.Sync:
+        break; // skip
+      case AsyncMarker.SyncYielding:
+        unexpected("async, async*, sync, or sync*", "$asyncModifier",
+            member.charOffset, uri);
+        break;
+    }
+
+    if (problem != null) {
+      // TODO(hillerstrom): once types get annotated with location
+      // information, we can improve the quality of the error message by
+      // using the offset of [returnType] (and the length of its name).
+      addProblem(problem, charOffset, length);
+    }
+  }
+
   /// Ensure that the containing library of the [member] has been loaded.
   ///
   /// This is for instance important for lazy dill library builders where this
@@ -4070,6 +4077,10 @@
       }
       FunctionDeclarationImpl.setHasImplicitReturnType(
           declaration, hasImplicitReturnType);
+      if (!hasImplicitReturnType) {
+        checkAsyncReturnType(asyncModifier, function.returnType,
+            variable.fileOffset, variable.name.length);
+      }
 
       variable.type = function.functionType;
       if (isFunctionExpression) {
@@ -5036,7 +5047,8 @@
           ..fileOffset = assignmentOffset;
       } else {
         if (formalType != null &&
-            !typeEnvironment.isSubtypeOf(formalType, builder.field.type)) {
+            !typeEnvironment.isSubtypeOf(formalType, builder.field.type,
+                SubtypeCheckMode.ignoringNullabilities)) {
           libraryBuilder.addProblem(
               fasta.templateInitializingFormalTypeMismatch
                   .withArguments(name, formalType, builder.field.type),
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 991fa4e..c588cd2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -26,6 +26,7 @@
 import 'package:kernel/core_types.dart' show CoreTypes;
 
 import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart';
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
@@ -1997,8 +1998,9 @@
   }
 
   @override
-  bool isSubtypeOf(DartType subtype, DartType supertype) {
-    return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+  bool isSubtypeOf(
+      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
+    return hierarchy.types.isSubtypeOfKernel(subtype, supertype, mode);
   }
 
   @override
@@ -2095,7 +2097,8 @@
             if (a.hadTypesInferred) {
               if (b.isSetter &&
                   (!impliesSetter(a) ||
-                      hierarchy.types.isSubtypeOfKernel(type, a.field.type))) {
+                      hierarchy.types.isSubtypeOfKernel(type, a.field.type,
+                          SubtypeCheckMode.ignoringNullabilities))) {
                 type = a.field.type;
               } else {
                 reportCantInferFieldType(classBuilder, a);
@@ -2263,9 +2266,11 @@
 
   bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
     if (isSetter) {
-      return hierarchy.types.isSubtypeOfKernel(b, a);
+      return hierarchy.types
+          .isSubtypeOfKernel(b, a, SubtypeCheckMode.ignoringNullabilities);
     } else {
-      return hierarchy.types.isSubtypeOfKernel(a, b);
+      return hierarchy.types
+          .isSubtypeOfKernel(a, b, SubtypeCheckMode.ignoringNullabilities);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 0821f5e..f477cee 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1858,7 +1858,8 @@
         }
       }
     }
-    return typeEnvironment.isSubtypeOf(constantType, type);
+    return typeEnvironment.isSubtypeOf(
+        constantType, type, SubtypeCheckMode.ignoringNullabilities);
   }
 
   Constant ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index e1f4092..2a22a37 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -1961,10 +1961,12 @@
       List<DartType> explicitTypeArguments,
       int extensionTypeParameterCount,
       {bool isNullAware}) {
+    assert(getterBuilder != null || setterBuilder != null);
     String targetName;
     Procedure readTarget;
     Procedure invokeTarget;
     if (getterBuilder != null) {
+      assert(!getterBuilder.isStatic);
       if (getterBuilder is AccessErrorBuilder) {
         AccessErrorBuilder error = getterBuilder;
         getterBuilder = error.builder;
@@ -1989,12 +1991,21 @@
       }
     }
     Procedure writeTarget;
-    if (setterBuilder is AccessErrorBuilder) {
-      targetName ??= setterBuilder.name;
-    } else if (setterBuilder != null && setterBuilder.isSetter) {
-      MemberBuilder memberBuilder = setterBuilder;
-      writeTarget = memberBuilder.member;
-      targetName ??= memberBuilder.name;
+    if (setterBuilder != null) {
+      assert(!setterBuilder.isStatic);
+      if (setterBuilder is AccessErrorBuilder) {
+        targetName ??= setterBuilder.name;
+      } else if (setterBuilder.isSetter) {
+        MemberBuilder memberBuilder = setterBuilder;
+        writeTarget = memberBuilder.member;
+        targetName ??= memberBuilder.name;
+      } else {
+        return unhandled(
+            "${setterBuilder.runtimeType}",
+            "InstanceExtensionAccessGenerator.fromBuilder",
+            offsetForToken(token),
+            helper.uri);
+      }
     }
     return new ExplicitExtensionInstanceAccessGenerator(
         helper,
@@ -2554,10 +2565,16 @@
     return _makeInvalidRead();
   }
 
-  Generator _createInstanceAccess(Name name, {bool isNullAware}) {
+  Generator _createInstanceAccess(Token token, Name name, {bool isNullAware}) {
     Builder getter = extensionBuilder.lookupLocalMember(name.name);
+    if (getter != null && getter.isStatic) {
+      getter = null;
+    }
     Builder setter =
         extensionBuilder.lookupLocalMember(name.name, setter: true);
+    if (setter != null && setter.isStatic) {
+      setter = null;
+    }
     if (getter == null && setter == null) {
       return new UnresolvedNameGenerator(_helper, token, name);
     }
@@ -2580,7 +2597,7 @@
           messageNotAConstantExpression, fileOffset, token.length);
     }
     Generator generator =
-        _createInstanceAccess(send.name, isNullAware: isNullAware);
+        _createInstanceAccess(send.token, send.name, isNullAware: isNullAware);
     if (send.arguments != null) {
       return generator.doInvocation(offsetForToken(send.token), send.arguments);
     } else {
@@ -2590,7 +2607,8 @@
 
   @override
   doInvocation(int offset, Arguments arguments) {
-    Generator generator = _createInstanceAccess(callName, isNullAware: false);
+    Generator generator =
+        _createInstanceAccess(token, callName, isNullAware: false);
     return generator.doInvocation(offset, arguments);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index 3c7ea2e..99e4ad8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -5,7 +5,7 @@
 library fasta.implicit_type;
 
 import 'package:kernel/ast.dart'
-    show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
+    show DartType, DartTypeVisitor, DartTypeVisitor1, Nullability, Visitor;
 
 import '../../scanner/token.dart' show Token;
 
@@ -18,11 +18,11 @@
   Token initializerToken;
   bool isStarted = false;
 
-  get nullability =>
-      unsupported("nullability", member.charOffset, member.fileUri);
-
   ImplicitFieldType(this.member, this.initializerToken);
 
+  Nullability get nullability =>
+      unsupported("nullability", member.charOffset, member.fileUri);
+
   R accept<R>(DartTypeVisitor<R> v) {
     throw unsupported("accept", member.charOffset, member.fileUri);
   }
@@ -34,4 +34,8 @@
   visitChildren(Visitor<Object> v) {
     unsupported("visitChildren", member.charOffset, member.fileUri);
   }
+
+  ImplicitFieldType withNullability(Nullability nullability) {
+    return unsupported("withNullability", member.charOffset, member.fileUri);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index 6cb9d18..e9a98e5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -5,7 +5,7 @@
 library fasta.implicit_type_argument;
 
 import 'package:kernel/ast.dart'
-    show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
+    show DartType, DartTypeVisitor, DartTypeVisitor1, Nullability, Visitor;
 
 import '../problems.dart' show unhandled, unsupported;
 
@@ -18,7 +18,7 @@
   const ImplicitTypeArgument();
 
   @override
-  get nullability => unsupported("nullability", -1, null);
+  Nullability get nullability => unsupported("nullability", -1, null);
 
   @override
   R accept<R>(DartTypeVisitor<R> v) {
@@ -34,4 +34,9 @@
   visitChildren(Visitor<Object> v) {
     unhandled("$runtimeType", "${v.runtimeType}", -1, null);
   }
+
+  @override
+  ImplicitTypeArgument withNullability(Nullability nullability) {
+    return unsupported("withNullability", -1, null);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 816cc1e..c1b4dc0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -366,12 +366,9 @@
     }
     bool hasExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(
-        typeContext,
-        node.fileOffset,
-        node.target.function.thisFunctionType,
-        computeConstructorReturnType(node.target),
-        node.arguments,
+    DartType inferredType = inferrer.inferInvocation(typeContext,
+        node.fileOffset, node.target.function.thisFunctionType, node.arguments,
+        returnType: computeConstructorReturnType(node.target),
         isConst: node.isConst);
     if (!inferrer.isTopLevel) {
       SourceLibraryBuilder library = inferrer.library;
@@ -396,8 +393,8 @@
         : new FunctionType([], const DynamicType());
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(typeContext,
-        node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+    DartType inferredType = inferrer.inferInvocation(
+        typeContext, node.fileOffset, calleeType, node.arguments);
     Expression replacement = new StaticInvocation(node.target, node.arguments);
     if (!inferrer.isTopLevel &&
         !hadExplicitTypeArguments &&
@@ -531,12 +528,9 @@
       FactoryConstructorInvocationJudgment node, DartType typeContext) {
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(
-        typeContext,
-        node.fileOffset,
-        node.target.function.thisFunctionType,
-        computeConstructorReturnType(node.target),
-        node.arguments,
+    DartType inferredType = inferrer.inferInvocation(typeContext,
+        node.fileOffset, node.target.function.thisFunctionType, node.arguments,
+        returnType: computeConstructorReturnType(node.target),
         isConst: node.isConst);
     node.hasBeenInferred = true;
     if (!inferrer.isTopLevel) {
@@ -795,8 +789,8 @@
         node.fileOffset,
         substitution.substituteType(
             node.target.function.thisFunctionType.withoutTypeParameters),
-        inferrer.thisType,
         node.argumentsJudgment,
+        returnType: inferrer.thisType,
         skipTypeArgumentInference: true);
   }
 
@@ -1386,9 +1380,13 @@
           mapEntryClass, <DartType>[actualKeyType, actualValueType]);
 
       bool isMap = inferrer.typeSchemaEnvironment.isSubtypeOf(
-          spreadType, inferrer.coreTypes.mapRawType(inferrer.library.nullable));
-      bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(spreadType,
-          inferrer.coreTypes.iterableRawType(inferrer.library.nullable));
+          spreadType,
+          inferrer.coreTypes.mapRawType(inferrer.library.nullable),
+          SubtypeCheckMode.ignoringNullabilities);
+      bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(
+          spreadType,
+          inferrer.coreTypes.iterableRawType(inferrer.library.nullable),
+          SubtypeCheckMode.ignoringNullabilities);
       if (isMap && !isIterable) {
         mapSpreadOffset = entry.fileOffset;
       }
@@ -4162,12 +4160,9 @@
       typeArguments[i] = new TypeParameterType(classTypeParameters[i]);
     }
     ArgumentsImpl.setNonInferrableArgumentTypes(node.arguments, typeArguments);
-    inferrer.inferInvocation(
-        null,
-        node.fileOffset,
-        node.target.function.thisFunctionType,
-        node.target.enclosingClass.thisType,
-        node.arguments,
+    inferrer.inferInvocation(null, node.fileOffset,
+        node.target.function.thisFunctionType, node.arguments,
+        returnType: node.target.enclosingClass.thisType,
         skipTypeArgumentInference: true);
     ArgumentsImpl.removeNonInferrableArgumentTypes(node.arguments);
   }
@@ -4313,8 +4308,8 @@
         : new FunctionType([], const DynamicType());
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(typeContext,
-        node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+    DartType inferredType = inferrer.inferInvocation(
+        typeContext, node.fileOffset, calleeType, node.arguments);
     if (!inferrer.isTopLevel &&
         !hadExplicitTypeArguments &&
         node.target != null) {
@@ -4356,8 +4351,8 @@
         node.fileOffset,
         substitution.substituteType(
             node.target.function.thisFunctionType.withoutTypeParameters),
-        inferrer.thisType,
         node.arguments,
+        returnType: inferrer.thisType,
         skipTypeArgumentInference: true);
   }
 
@@ -4620,8 +4615,8 @@
         inferrer.typeSchemaEnvironment.futureType(const DynamicType());
     if (node.arguments != null) {
       FunctionType calleeType = new FunctionType([], inferredType);
-      inferrer.inferInvocation(typeContext, node.fileOffset, calleeType,
-          calleeType.returnType, node.arguments);
+      inferrer.inferInvocation(
+          typeContext, node.fileOffset, calleeType, node.arguments);
     }
     return new ExpressionInferenceResult(inferredType);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 627fbc5..e1dbaf4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -24,6 +24,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart';
+
 import 'package:kernel/clone.dart';
 
 import '../../base/instrumentation.dart'
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index 6e519f9..0e7d4d4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -46,7 +46,8 @@
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+    show SubtypeCheckMode, TypeEnvironment;
 
 import 'package:kernel/visitor.dart' show Transformer;
 
@@ -248,7 +249,8 @@
     VariableDeclaration elt;
     Statement loopBody;
     if (element.elementType == null ||
-        !typeEnvironment.isSubtypeOf(element.elementType, elementType)) {
+        !typeEnvironment.isSubtypeOf(element.elementType, elementType,
+            SubtypeCheckMode.ignoringNullabilities)) {
       elt = new VariableDeclaration(null,
           type: const DynamicType(), isFinal: true);
       VariableDeclaration castedVar = new VariableDeclaration.forValue(
@@ -439,7 +441,8 @@
     VariableDeclaration elt;
     Statement loopBody;
     if (entry.entryType == null ||
-        !typeEnvironment.isSubtypeOf(entry.entryType, entryType)) {
+        !typeEnvironment.isSubtypeOf(entry.entryType, entryType,
+            SubtypeCheckMode.ignoringNullabilities)) {
       elt = new VariableDeclaration(null,
           type: new InterfaceType(mapEntryClass,
               <DartType>[const DynamicType(), const DynamicType()]),
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 544ff1d..bcceaad 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -120,6 +120,29 @@
   return Variance.unrelated;
 }
 
+/// Combines syntactic nullabilities on types for performing type substitution.
+///
+/// The syntactic substitution should preserve a `?` if it was either on the
+/// type parameter occurrence or on the type argument replacing it.
+NullabilityBuilder combineNullabilityBuildersForSubstitution(
+    NullabilityBuilder a, NullabilityBuilder b) {
+  assert(
+      (identical(a, const NullabilityBuilder.nullable()) ||
+              identical(a, const NullabilityBuilder.omitted())) &&
+          (identical(b, const NullabilityBuilder.nullable()) ||
+              identical(b, const NullabilityBuilder.omitted())),
+      "Both arguments to combineNullabilityBuildersForSubstitution "
+      "should be identical to either 'const NullabilityBuilder.nullable()' or "
+      "'const NullabilityBuilder.omitted()'.");
+
+  if (identical(a, const NullabilityBuilder.nullable()) ||
+      identical(b, const NullabilityBuilder.nullable())) {
+    return const NullabilityBuilder.nullable();
+  }
+
+  return const NullabilityBuilder.omitted();
+}
+
 TypeBuilder substituteRange(
     TypeBuilder type,
     Map<TypeVariableBuilder, TypeBuilder> upperSubstitution,
@@ -130,9 +153,21 @@
   if (type is NamedTypeBuilder) {
     if (type.declaration is TypeVariableBuilder) {
       if (variance == Variance.contravariant) {
-        return lowerSubstitution[type.declaration] ?? type;
+        TypeBuilder replacement = lowerSubstitution[type.declaration];
+        if (replacement != null) {
+          return replacement.withNullabilityBuilder(
+              combineNullabilityBuildersForSubstitution(
+                  replacement.nullabilityBuilder, type.nullabilityBuilder));
+        }
+        return type;
       }
-      return upperSubstitution[type.declaration] ?? type;
+      TypeBuilder replacement = upperSubstitution[type.declaration];
+      if (replacement != null) {
+        return replacement.withNullabilityBuilder(
+            combineNullabilityBuildersForSubstitution(
+                replacement.nullabilityBuilder, type.nullabilityBuilder));
+      }
+      return type;
     }
     if (type.arguments == null || type.arguments.length == 0) {
       return type;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 45d0275..0bb51ac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -178,6 +178,7 @@
           result.add(" extends ");
           param.bound.accept(this);
         }
+        first = false;
       }
       result.add(">");
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
index a70d416..bf19015 100644
--- a/pkg/front_end/lib/src/fasta/kernel/types.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/types.dart
@@ -22,6 +22,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart';
+
 import 'kernel_builder.dart' show ClassHierarchyBuilder;
 
 class Types {
@@ -30,7 +32,7 @@
   Types(this.hierarchy);
 
   /// Returns true if [s] is a subtype of [t].
-  bool isSubtypeOfKernel(DartType s, DartType t) {
+  bool isSubtypeOfKernel(DartType s, DartType t, SubtypeCheckMode mode) {
     if (s is InvalidType) {
       // InvalidType is a bottom type.
       return true;
@@ -231,13 +233,15 @@
       throw "Numbers of type arguments don't match $s $t.";
     }
     for (int i = 0; i < s.length; i++) {
-      if (!isSubtypeOfKernel(s[i], t[i])) return false;
+      if (!isSubtypeOfKernel(
+          s[i], t[i], SubtypeCheckMode.ignoringNullabilities)) return false;
     }
     return true;
   }
 
   bool isSameTypeKernel(DartType s, DartType t) {
-    return isSubtypeOfKernel(s, t) && isSubtypeOfKernel(t, s);
+    return isSubtypeOfKernel(s, t, SubtypeCheckMode.ignoringNullabilities) &&
+        isSubtypeOfKernel(t, s, SubtypeCheckMode.ignoringNullabilities);
   }
 }
 
@@ -301,7 +305,8 @@
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       InterfaceType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s.parameter.bound, t);
+    return types.isSubtypeOfKernel(
+        s.parameter.bound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -312,11 +317,14 @@
       Nullability tNullability,
       Types types) {
     List<DartType> arguments = futureOr.typeArguments;
-    if (!types.isSubtypeOfKernel(arguments.single, t)) {
+    if (!types.isSubtypeOfKernel(
+        arguments.single, t, SubtypeCheckMode.ignoringNullabilities)) {
       return false; // Rule 7.1
     }
     if (!types.isSubtypeOfKernel(
-        new InterfaceType(types.hierarchy.futureClass, arguments), t)) {
+        new InterfaceType(types.hierarchy.futureClass, arguments),
+        t,
+        SubtypeCheckMode.ignoringNullabilities)) {
       return false; // Rule 7.2
     }
     return true;
@@ -329,7 +337,8 @@
       InterfaceType t,
       Nullability tNullability,
       Types types) {
-    return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
+    return types.isSubtypeOfKernel(intersection.promotedBound, t,
+        SubtypeCheckMode.ignoringNullabilities); // Rule 12.
   }
 
   @override
@@ -348,7 +357,8 @@
   bool isTypedefRelated(TypedefType s, Nullability sNullability,
       InterfaceType t, Nullability tNullability, Types types) {
     // Rule 5.
-    return types.isSubtypeOfKernel(s.unalias, t);
+    return types.isSubtypeOfKernel(
+        s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -397,7 +407,10 @@
       }
       s = substitution.substituteType(s.withoutTypeParameters);
     }
-    if (!types.isSubtypeOfKernel(s.returnType, t.returnType)) return false;
+    if (!types.isSubtypeOfKernel(
+        s.returnType, t.returnType, SubtypeCheckMode.ignoringNullabilities)) {
+      return false;
+    }
     List<DartType> sPositional = s.positionalParameters;
     List<DartType> tPositional = t.positionalParameters;
     if (s.requiredParameterCount > t.requiredParameterCount) {
@@ -409,7 +422,8 @@
       return false;
     }
     for (int i = 0; i < tPositional.length; i++) {
-      if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i])) {
+      if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i],
+          SubtypeCheckMode.ignoringNullabilities)) {
         // Rule 15, Tj <: Sj.
         return false;
       }
@@ -431,8 +445,8 @@
           if (sNamed[sCount].name == name) break;
         }
         if (sCount == sNamed.length) return false;
-        if (!types.isSubtypeOfKernel(
-            tNamed[tCount].type, sNamed[sCount].type)) {
+        if (!types.isSubtypeOfKernel(tNamed[tCount].type, sNamed[sCount].type,
+            SubtypeCheckMode.ignoringNullabilities)) {
           return false;
         }
       }
@@ -470,21 +484,24 @@
       Nullability tNullability,
       Types types) {
     // Rule 12.
-    return types.isSubtypeOfKernel(intersection.promotedBound, t);
+    return types.isSubtypeOfKernel(
+        intersection.promotedBound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       FunctionType t, Nullability tNullability, Types types) {
     // Rule 13.
-    return types.isSubtypeOfKernel(s.parameter.bound, t);
+    return types.isSubtypeOfKernel(
+        s.parameter.bound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability, FunctionType t,
       Nullability tNullability, Types types) {
     // Rule 5.
-    return types.isSubtypeOfKernel(s.unalias, t);
+    return types.isSubtypeOfKernel(
+        s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -502,7 +519,8 @@
       TypeParameterType t, Nullability tNullability, Types types) {
     return s.parameter == t.parameter ||
         // Rule 13.
-        types.isSubtypeOfKernel(s.bound, t);
+        types.isSubtypeOfKernel(
+            s.bound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -546,7 +564,8 @@
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability,
       TypeParameterType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s.unalias, t);
+    return types.isSubtypeOfKernel(
+        s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -562,19 +581,22 @@
   @override
   bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
       TypedefType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isDynamicRelated(DynamicType s, Nullability sNullability, TypedefType t,
       Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isFunctionRelated(FunctionType s, Nullability sNullability,
       TypedefType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -584,7 +606,8 @@
       TypedefType t,
       Nullability tNullability,
       Types types) {
-    return types.isSubtypeOfKernel(futureOr, t.unalias);
+    return types.isSubtypeOfKernel(
+        futureOr, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -594,25 +617,29 @@
       TypedefType t,
       Nullability tNullability,
       Types types) {
-    return types.isSubtypeOfKernel(intersection, t.unalias);
+    return types.isSubtypeOfKernel(
+        intersection, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       TypedefType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability, TypedefType t,
       Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s.unalias, t.unalias);
+    return types.isSubtypeOfKernel(
+        s.unalias, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isVoidRelated(VoidType s, Nullability sNullability, TypedefType t,
       Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 }
 
@@ -623,12 +650,15 @@
   bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     List<DartType> arguments = futureOr.typeArguments;
-    if (types.isSubtypeOfKernel(s, arguments.single)) {
+    if (types.isSubtypeOfKernel(
+        s, arguments.single, SubtypeCheckMode.ignoringNullabilities)) {
       return true; // Rule 11.
     }
     // Rule 10.
     return types.isSubtypeOfKernel(
-        s, new InterfaceType(types.hierarchy.futureClass, arguments));
+        s,
+        new InterfaceType(types.hierarchy.futureClass, arguments),
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -639,48 +669,55 @@
       Nullability tFutureOrNullability,
       Types types) {
     // This follows from combining rules 7, 10, and 11.
-    return types.isSubtypeOfKernel(
-        sFutureOr.typeArguments.single, tFutureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(sFutureOr.typeArguments.single,
+        tFutureOr.typeArguments.single, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isDynamicRelated(DynamicType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
-    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isVoidRelated(VoidType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
-    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     List<DartType> arguments = futureOr.typeArguments;
-    if (types.isSubtypeOfKernel(s, arguments.single)) {
+    if (types.isSubtypeOfKernel(
+        s, arguments.single, SubtypeCheckMode.ignoringNullabilities)) {
       // Rule 11.
       return true;
     }
 
-    if (types.isSubtypeOfKernel(s.parameter.bound, futureOr)) {
+    if (types.isSubtypeOfKernel(
+        s.parameter.bound, futureOr, SubtypeCheckMode.ignoringNullabilities)) {
       // Rule 13.
       return true;
     }
 
     // Rule 10.
     return types.isSubtypeOfKernel(
-        s, new InterfaceType(types.hierarchy.futureClass, arguments));
+        s,
+        new InterfaceType(types.hierarchy.futureClass, arguments),
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isFunctionRelated(FunctionType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
-    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -696,13 +733,15 @@
       return true;
     }
     // Rule 12.
-    return types.isSubtypeOfKernel(intersection.promotedBound, futureOr);
+    return types.isSubtypeOfKernel(intersection.promotedBound, futureOr,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
-    return types.isSubtypeOfKernel(s.unalias, futureOr);
+    return types.isSubtypeOfKernel(
+        s.unalias, futureOr, SubtypeCheckMode.ignoringNullabilities);
   }
 }
 
@@ -723,7 +762,8 @@
             tIntersection,
             tIntersectionNullability,
             types) &&
-        types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
+        types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound,
+            SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -736,7 +776,8 @@
     // Rule 9.
     return const IsTypeParameterSubtypeOf().isTypeParameterRelated(
             s, sNullability, intersection, intersectionNullability, types) &&
-        types.isSubtypeOfKernel(s, intersection.promotedBound);
+        types.isSubtypeOfKernel(s, intersection.promotedBound,
+            SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -787,7 +828,8 @@
       Nullability intersectionNullability,
       Types types) {
     // Rule 5.
-    return types.isSubtypeOfKernel(s.unalias, intersection);
+    return types.isSubtypeOfKernel(
+        s.unalias, intersection, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index f2753bd..9e548fb 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -3444,7 +3444,7 @@
               beforeInitializers?.next, token);
           break;
         case DeclarationKind.Extension:
-          if (optional(';', bodyStart)) {
+          if (optional(';', bodyStart) && externalToken == null) {
             reportRecoverableError(isOperator ? name.next : name,
                 fasta.messageExtensionDeclaresAbstractMember);
           }
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index fd7df17..09ac319 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -4,6 +4,7 @@
 
 import 'dart:core' hide MapEntry;
 import 'package:kernel/ast.dart';
+import '../../base/common.dart';
 import '../builder/declaration.dart';
 import '../builder/extension_builder.dart';
 import '../builder/library_builder.dart';
@@ -12,22 +13,26 @@
 import '../builder/type_builder.dart';
 import '../builder/type_variable_builder.dart';
 import '../scope.dart';
-import 'source_library_builder.dart';
 import '../kernel/kernel_builder.dart';
-
 import '../problems.dart';
-
 import '../fasta_codes.dart'
     show
+        messagePatchDeclarationMismatch,
+        messagePatchDeclarationOrigin,
         noLength,
         templateConflictsWithMember,
         templateConflictsWithMemberWarning,
         templateConflictsWithSetter,
-        templateConflictsWithSetterWarning;
+        templateConflictsWithSetterWarning,
+        templateExtensionMemberConflictsWithObjectMember;
+import 'source_library_builder.dart';
 
 class SourceExtensionBuilder extends ExtensionBuilder {
   final Extension _extension;
 
+  SourceExtensionBuilder _origin;
+  SourceExtensionBuilder patchForTesting;
+
   SourceExtensionBuilder(
       List<MetadataBuilder> metadata,
       int modifiers,
@@ -48,7 +53,10 @@
         super(metadata, modifiers, name, parent, nameOffset, scope,
             typeParameters, onType);
 
-  Extension get extension => _extension;
+  @override
+  SourceExtensionBuilder get origin => _origin ?? this;
+
+  Extension get extension => isPatch ? origin._extension : _extension;
 
   /// Builds the [Extension] for this extension build and inserts the members
   /// into the [Library] of [libraryBuilder].
@@ -61,8 +69,20 @@
   Extension build(
       SourceLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary,
       {bool addMembersToLibrary}) {
+    ClassBuilder objectClassBuilder =
+        coreLibrary.lookupLocalMember('Object', required: true);
     void buildBuilders(String name, Builder declaration) {
       do {
+        Builder objectGetter = objectClassBuilder.lookupLocalMember(name);
+        Builder objectSetter =
+            objectClassBuilder.lookupLocalMember(name, setter: true);
+        if (objectGetter != null || objectSetter != null) {
+          addProblem(
+              templateExtensionMemberConflictsWithObjectMember
+                  .withArguments(name),
+              declaration.charOffset,
+              name.length);
+        }
         if (declaration.parent != this) {
           if (fileUri != declaration.parent.fileUri) {
             unexpected("$fileUri", "${declaration.parent.fileUri}", charOffset,
@@ -75,7 +95,7 @@
           Field field = declaration.build(libraryBuilder);
           if (addMembersToLibrary && declaration.next == null) {
             libraryBuilder.library.addMember(field);
-            _extension.members.add(new ExtensionMemberDescriptor(
+            extension.members.add(new ExtensionMemberDescriptor(
                 name: new Name(declaration.name, libraryBuilder.library),
                 member: field.reference,
                 isStatic: declaration.isStatic,
@@ -83,7 +103,9 @@
           }
         } else if (declaration is ProcedureBuilder) {
           Member function = declaration.build(libraryBuilder);
-          if (addMembersToLibrary && declaration.next == null) {
+          if (addMembersToLibrary &&
+              !declaration.isPatch &&
+              declaration.next == null) {
             libraryBuilder.library.addMember(function);
             ExtensionMemberKind kind;
             switch (declaration.kind) {
@@ -103,11 +125,10 @@
                 unsupported("Extension method kind: ${declaration.kind}",
                     declaration.charOffset, declaration.fileUri);
             }
-            _extension.members.add(new ExtensionMemberDescriptor(
+            extension.members.add(new ExtensionMemberDescriptor(
                 name: new Name(declaration.name, libraryBuilder.library),
                 member: function.reference,
                 isStatic: declaration.isStatic,
-                isExternal: declaration.isExternal,
                 kind: kind));
             Procedure tearOff = declaration.extensionTearOff;
             if (tearOff != null) {
@@ -116,7 +137,6 @@
                   name: new Name(declaration.name, libraryBuilder.library),
                   member: tearOff.reference,
                   isStatic: false,
-                  isExternal: false,
                   kind: ExtensionMemberKind.TearOff));
             }
           }
@@ -157,4 +177,46 @@
 
     return _extension;
   }
+
+  @override
+  void applyPatch(Builder patch) {
+    if (patch is SourceExtensionBuilder) {
+      patch._origin = this;
+      if (retainDataForTesting) {
+        patchForTesting = patch;
+      }
+      scope.local.forEach((String name, Builder member) {
+        Builder memberPatch = patch.scope.local[name];
+        if (memberPatch != null) {
+          member.applyPatch(memberPatch);
+        }
+      });
+      scope.setters.forEach((String name, Builder member) {
+        Builder memberPatch = patch.scope.setters[name];
+        if (memberPatch != null) {
+          member.applyPatch(memberPatch);
+        }
+      });
+
+      // TODO(johnniwinther): Check that type parameters and on-type match
+      // with origin declaration.
+    } else {
+      library.addProblem(messagePatchDeclarationMismatch, patch.charOffset,
+          noLength, patch.fileUri, context: [
+        messagePatchDeclarationOrigin.withLocation(
+            fileUri, charOffset, noLength)
+      ]);
+    }
+  }
+
+  @override
+  int finishPatch() {
+    if (!isPatch) return 0;
+
+    int count = 0;
+    scope.forEach((String name, Builder declaration) {
+      count += declaration.finishPatch();
+    });
+    return count;
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index f2243b2..83ce151 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -20,6 +20,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
 import 'type_schema.dart' show UnknownType;
 
 abstract class StandardBounds {
@@ -30,7 +32,7 @@
   InterfaceType get objectLegacyRawType;
   InterfaceType get functionLegacyRawType;
 
-  bool isSubtypeOf(DartType subtype, DartType supertype);
+  bool isSubtypeOf(DartType subtype, DartType supertype, SubtypeCheckMode mode);
 
   InterfaceType getLegacyLeastUpperBound(
       InterfaceType type1, InterfaceType type2);
@@ -94,11 +96,11 @@
 
     // Otherwise, the lower bounds  of two types is one of them it if it is a
     // subtype of the other.
-    if (isSubtypeOf(type1, type2)) {
+    if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
       return type1;
     }
 
-    if (isSubtypeOf(type2, type1)) {
+    if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
       return type2;
     }
 
@@ -408,10 +410,10 @@
     // 3. Otherwise return the spec-defined standard upper bound.  This will
     //    be an upper bound, might (or might not) be least, and might
     //    (or might not) be a well-formed type.
-    if (isSubtypeOf(type1, type2)) {
+    if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
       return type2;
     }
-    if (isSubtypeOf(type2, type1)) {
+    if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
       return type1;
     }
     if (type1 is InterfaceType &&
@@ -463,10 +465,10 @@
     // type variable first.  Alternatively, you could probably choose to treat
     // it as just an instance of the interface type upper bound problem, with
     // the "inheritance" chain extended by the bounds placed on the variables.
-    if (isSubtypeOf(type1, type2)) {
+    if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
       return type2;
     }
-    if (isSubtypeOf(type2, type1)) {
+    if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
       return type1;
     }
     if (type1 is TypeParameterType) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index faf4afd..e51fb8d 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -12,8 +12,9 @@
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'package:kernel/type_algebra.dart'
-    show FreshTypeParameters, getFreshTypeParameters, Substitution;
+import 'package:kernel/type_algebra.dart';
+
+import 'package:kernel/type_environment.dart';
 
 import 'package:kernel/src/bounds_checks.dart' show calculateBounds;
 
@@ -349,8 +350,8 @@
     assert(_needToInferReturnType);
     DartType inferredType =
         inferrer.inferReturnType(_inferredUnwrappedReturnOrYieldType);
-    if (!inferrer.typeSchemaEnvironment
-        .isSubtypeOf(inferredType, returnOrYieldContext)) {
+    if (!inferrer.typeSchemaEnvironment.isSubtypeOf(inferredType,
+        returnOrYieldContext, SubtypeCheckMode.ignoringNullabilities)) {
       // If the inferred return type isn't a subtype of the context, we use the
       // context.
       inferredType = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
@@ -525,8 +526,10 @@
   }
 
   bool isAssignable(DartType expectedType, DartType actualType) {
-    return typeSchemaEnvironment.isSubtypeOf(expectedType, actualType) ||
-        typeSchemaEnvironment.isSubtypeOf(actualType, expectedType);
+    return typeSchemaEnvironment.isSubtypeOf(
+            expectedType, actualType, SubtypeCheckMode.ignoringNullabilities) ||
+        typeSchemaEnvironment.isSubtypeOf(
+            actualType, expectedType, SubtypeCheckMode.ignoringNullabilities);
   }
 
   /// Checks whether [actualType] can be assigned to the greatest closure of
@@ -602,12 +605,14 @@
     }
 
     if (expectedType == null ||
-        typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
+        typeSchemaEnvironment.isSubtypeOf(
+            actualType, expectedType, SubtypeCheckMode.ignoringNullabilities)) {
       // Types are compatible.
       return null;
     }
 
-    if (!typeSchemaEnvironment.isSubtypeOf(expectedType, actualType)) {
+    if (!typeSchemaEnvironment.isSubtypeOf(
+        expectedType, actualType, SubtypeCheckMode.ignoringNullabilities)) {
       // Error: not assignable.  Perform error recovery.
       TreeNode parent = expression.parent;
       Expression errorNode = new AsExpression(
@@ -790,7 +795,8 @@
               DartType typeArgument = inferredTypeArguments[index];
               DartType bound =
                   inferredSubstitution.substituteType(typeParameter.bound);
-              if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound)) {
+              if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound,
+                  SubtypeCheckMode.ignoringNullabilities)) {
                 return;
               }
             }
@@ -805,7 +811,8 @@
                 .substituteType(extensionBuilder.extension.onType);
           }
 
-          if (typeSchemaEnvironment.isSubtypeOf(receiverType, onType)) {
+          if (typeSchemaEnvironment.isSubtypeOf(
+              receiverType, onType, SubtypeCheckMode.ignoringNullabilities)) {
             ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
                 onType,
                 onTypeInstantiateToBounds,
@@ -1639,26 +1646,33 @@
   }
 
   DartType inferInvocation(DartType typeContext, int offset,
-      FunctionType calleeType, DartType returnType, Arguments arguments,
+      FunctionType calleeType, Arguments arguments,
       {bool isOverloadedArithmeticOperator: false,
+      DartType returnType,
       DartType receiverType,
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false}) {
+    assert(
+        returnType == null || !containsFreeFunctionTypeVariables(returnType),
+        "Return type $returnType contains free variables."
+        "Provided function type: $calleeType.");
     int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
     if (extensionTypeParameterCount != 0) {
+      assert(returnType == null,
+          "Unexpected explicit return type for extension method invocation.");
       return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
-          typeContext, offset, calleeType, returnType, arguments,
+          typeContext, offset, calleeType, arguments,
           isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
           receiverType: receiverType,
           skipTypeArgumentInference: skipTypeArgumentInference,
           isConst: isConst,
           isImplicitExtensionMember: isImplicitExtensionMember);
     }
-    return _inferInvocation(
-        typeContext, offset, calleeType, returnType, arguments,
+    return _inferInvocation(typeContext, offset, calleeType, arguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         receiverType: receiverType,
+        returnType: returnType,
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst,
         isImplicitExtensionMember: isImplicitExtensionMember);
@@ -1669,7 +1683,6 @@
       DartType typeContext,
       int offset,
       FunctionType calleeType,
-      DartType returnType,
       Arguments arguments,
       {bool isOverloadedArithmeticOperator: false,
       DartType receiverType,
@@ -1685,8 +1698,8 @@
     Arguments extensionArguments = helper.forest.createArguments(
         arguments.fileOffset, [arguments.positional.first],
         types: getExplicitExtensionTypeArguments(arguments));
-    _inferInvocation(const UnknownType(), offset, extensionFunctionType,
-        extensionFunctionType.returnType, extensionArguments,
+    _inferInvocation(
+        const UnknownType(), offset, extensionFunctionType, extensionArguments,
         skipTypeArgumentInference: skipTypeArgumentInference,
         receiverType: receiverType,
         isImplicitExtensionMember: isImplicitExtensionMember);
@@ -1705,13 +1718,11 @@
         typeParameters: targetTypeParameters);
     targetFunctionType =
         extensionSubstitution.substituteType(targetFunctionType);
-    DartType targetReturnType =
-        extensionSubstitution.substituteType(returnType);
     Arguments targetArguments = helper.forest.createArguments(
         arguments.fileOffset, arguments.positional.skip(1).toList(),
         named: arguments.named, types: getExplicitTypeArguments(arguments));
-    DartType inferredType = _inferInvocation(typeContext, offset,
-        targetFunctionType, targetReturnType, targetArguments,
+    DartType inferredType = _inferInvocation(
+        typeContext, offset, targetFunctionType, targetArguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst);
@@ -1731,13 +1742,18 @@
   /// Performs the type inference steps that are shared by all kinds of
   /// invocations (constructors, instance methods, and static methods).
   DartType _inferInvocation(DartType typeContext, int offset,
-      FunctionType calleeType, DartType returnType, Arguments arguments,
+      FunctionType calleeType, Arguments arguments,
       {bool isOverloadedArithmeticOperator: false,
       bool isBinaryOperator: false,
       DartType receiverType,
+      DartType returnType,
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false}) {
+    assert(
+        returnType == null || !containsFreeFunctionTypeVariables(returnType),
+        "Return type $returnType contains free variables."
+        "Provided function type: $calleeType.");
     lastInferredSubstitution = null;
     lastCalleeType = null;
     List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
@@ -1753,7 +1769,9 @@
       // in which me must do this, to avoid a performance regression?
       FreshTypeParameters fresh = getFreshTypeParameters(calleeTypeParameters);
       calleeType = fresh.applyToFunctionType(calleeType);
-      returnType = fresh.substitute(returnType);
+      if (returnType != null) {
+        returnType = fresh.substitute(returnType);
+      }
       calleeTypeParameters = fresh.freshTypeParameters;
     }
     List<DartType> explicitTypeArguments = getExplicitTypeArguments(arguments);
@@ -1776,8 +1794,13 @@
       }
       inferredTypes = new List<DartType>.filled(
           calleeTypeParameters.length, const UnknownType());
-      typeSchemaEnvironment.inferGenericFunctionOrType(returnType,
-          calleeTypeParameters, null, null, typeContext, inferredTypes);
+      typeSchemaEnvironment.inferGenericFunctionOrType(
+          returnType ?? calleeType.returnType,
+          calleeTypeParameters,
+          null,
+          null,
+          typeContext,
+          inferredTypes);
       substitution =
           Substitution.fromPairs(calleeTypeParameters, inferredTypes);
     } else if (explicitTypeArguments != null &&
@@ -1869,7 +1892,7 @@
 
     if (inferenceNeeded) {
       typeSchemaEnvironment.inferGenericFunctionOrType(
-          returnType,
+          returnType ?? calleeType.returnType,
           calleeTypeParameters,
           formalTypes,
           actualTypes,
@@ -1912,9 +1935,21 @@
     DartType inferredType;
     lastInferredSubstitution = substitution;
     lastCalleeType = calleeType;
-    inferredType = substitution == null
-        ? returnType
-        : substitution.substituteType(returnType);
+    if (returnType != null) {
+      inferredType = substitution == null
+          ? returnType
+          : substitution.substituteType(returnType);
+    } else {
+      if (substitution != null) {
+        calleeType =
+            substitution.substituteType(calleeType.withoutTypeParameters);
+      }
+      inferredType = calleeType.returnType;
+    }
+    assert(
+        !containsFreeFunctionTypeVariables(inferredType),
+        "Inferred return type $inferredType contains free variables."
+        "Inferred function type: $calleeType.");
     return inferredType;
   }
 
@@ -2142,8 +2177,8 @@
           target, node, node.receiver, arguments);
       arguments = replacement.arguments;
     }
-    DartType inferredType = inferInvocation(typeContext, node.fileOffset,
-        functionType, functionType.returnType, arguments,
+    DartType inferredType = inferInvocation(
+        typeContext, node.fileOffset, functionType, arguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         receiverType: receiverType,
         isImplicitExtensionMember: target.isExtensionMember);
@@ -2252,8 +2287,8 @@
       parent?.replaceChild(expression, error);
       return const ExpressionInferenceResult(const DynamicType());
     }
-    DartType inferredType = inferInvocation(typeContext, fileOffset,
-        functionType, functionType.returnType, arguments,
+    DartType inferredType = inferInvocation(
+        typeContext, fileOffset, functionType, arguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         receiverType: receiverType,
         isImplicitExtensionMember: target.isExtensionMember);
@@ -2614,7 +2649,8 @@
     }
     if (expectedType is FunctionType) return true;
     if (expectedType == typeSchemaEnvironment.functionLegacyRawType) {
-      if (!typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
+      if (!typeSchemaEnvironment.isSubtypeOf(
+          actualType, expectedType, SubtypeCheckMode.ignoringNullabilities)) {
         return true;
       }
     }
@@ -2915,10 +2951,10 @@
       ExtensionAccessCandidate other) {
     if (this.isPlatform == other.isPlatform) {
       // Both are platform or not platform.
-      bool thisIsSubtype =
-          typeSchemaEnvironment.isSubtypeOf(this.onType, other.onType);
-      bool thisIsSupertype =
-          typeSchemaEnvironment.isSubtypeOf(other.onType, this.onType);
+      bool thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
+          this.onType, other.onType, SubtypeCheckMode.ignoringNullabilities);
+      bool thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
+          other.onType, this.onType, SubtypeCheckMode.ignoringNullabilities);
       if (thisIsSubtype && !thisIsSupertype) {
         // This is subtype of other and not vice-versa.
         return true;
@@ -2927,9 +2963,13 @@
         return false;
       } else if (thisIsSubtype || thisIsSupertype) {
         thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
-            this.onTypeInstantiateToBounds, other.onTypeInstantiateToBounds);
+            this.onTypeInstantiateToBounds,
+            other.onTypeInstantiateToBounds,
+            SubtypeCheckMode.ignoringNullabilities);
         thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
-            other.onTypeInstantiateToBounds, this.onTypeInstantiateToBounds);
+            other.onTypeInstantiateToBounds,
+            this.onTypeInstantiateToBounds,
+            SubtypeCheckMode.ignoringNullabilities);
         if (thisIsSubtype && !thisIsSupertype) {
           // This is subtype of other and not vice-versa.
           return true;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
index f8f0ff5..bb90d9d 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
@@ -5,6 +5,8 @@
 import 'package:kernel/ast.dart'
     show DartType, Expression, TypeParameterType, VariableDeclaration;
 
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
 import '../fasta_codes.dart' show templateInternalProblemStackNotEmpty;
 
 import '../problems.dart' show internalProblem;
@@ -682,16 +684,18 @@
     // What we do now depends on the relationship between the previous type of
     // the variable and the type we are checking against.
     DartType previousType = previousPromotedType ?? variable.type;
-    if (promoter.typeSchemaEnvironment.isSubtypeOf(checkedType, previousType)) {
+    if (promoter.typeSchemaEnvironment.isSubtypeOf(
+        checkedType, previousType, SubtypeCheckMode.ignoringNullabilities)) {
       // The type we are checking against is a subtype of the previous type of
       // the variable, so this is a refinement; we can promote.
       return checkedType;
     } else if (previousType is TypeParameterType &&
-        promoter.typeSchemaEnvironment
-            .isSubtypeOf(checkedType, previousType.bound)) {
+        promoter.typeSchemaEnvironment.isSubtypeOf(checkedType,
+            previousType.bound, SubtypeCheckMode.ignoringNullabilities)) {
       // The type we are checking against is a subtype of the bound of the
       // previous type of the variable; we can promote the bound.
-      return new TypeParameterType(previousType.parameter, checkedType);
+      return new TypeParameterType(
+          previousType.parameter, checkedType, previousType.nullability);
     } else {
       // The types aren't sufficiently related; we can't promote.
       return previousPromotedType;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index 1634efb..6a2aa4e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -10,6 +10,7 @@
         FunctionType,
         InterfaceType,
         NamedType,
+        Nullability,
         TypedefType,
         Visitor;
 
@@ -18,8 +19,6 @@
 import 'package:kernel/text/ast_to_text.dart'
     show Annotator, NameSystem, Printer, globalDebuggingNames;
 
-import '../problems.dart' show unsupported;
-
 /// Determines whether a type schema contains `?` somewhere inside it.
 bool isKnown(DartType schema) => schema.accept(new _IsKnownVisitor());
 
@@ -60,7 +59,7 @@
 /// purely part of the local inference process.
 class UnknownType extends DartType {
   @override
-  get nullability => unsupported("nullability", -1, null);
+  Nullability get nullability => null;
 
   const UnknownType();
 
@@ -81,6 +80,9 @@
 
   @override
   visitChildren(Visitor<dynamic> v) {}
+
+  @override
+  UnknownType withNullability(Nullability nullability) => this;
 }
 
 /// Visitor that computes [isKnown].
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 5f8280e..8339567 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -19,6 +19,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
 import 'package:kernel/src/hierarchy_based_type_environment.dart'
     show HierarchyBasedTypeEnvironment;
 
@@ -267,7 +269,8 @@
       if (success && !hasOmittedBound(typeParam)) {
         // If everything else succeeded, check the `extends` constraint.
         DartType extendsConstraint = typeParamBound;
-        success = isSubtypeOf(inferred, extendsConstraint);
+        success = isSubtypeOf(inferred, extendsConstraint,
+            SubtypeCheckMode.ignoringNullabilities);
       }
 
       if (!success) {
@@ -288,10 +291,11 @@
   }
 
   @override
-  bool isSubtypeOf(DartType subtype, DartType supertype) {
+  bool isSubtypeOf(
+      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
     if (subtype is UnknownType) return true;
     if (subtype == Null && supertype is UnknownType) return true;
-    return super.isSubtypeOf(subtype, supertype);
+    return super.isSubtypeOf(subtype, supertype, mode);
   }
 
   bool isEmptyContext(DartType context) {
@@ -359,8 +363,10 @@
 
   /// Determine if the given [type] satisfies the given type [constraint].
   bool typeSatisfiesConstraint(DartType type, TypeConstraint constraint) {
-    return isSubtypeOf(constraint.lower, type) &&
-        isSubtypeOf(type, constraint.upper);
+    return isSubtypeOf(
+            constraint.lower, type, SubtypeCheckMode.ignoringNullabilities) &&
+        isSubtypeOf(
+            type, constraint.upper, SubtypeCheckMode.ignoringNullabilities);
   }
 
   DartType _inferTypeParameterFromAll(DartType typeFromContextInference,
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index 0afbb82..a7be604 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -61,9 +61,8 @@
 
   DataExtractor(this.actualMap);
 
-  void computeForLibrary(Library library, {bool useFileUri: false}) {
-    LibraryId id =
-        new LibraryId(useFileUri ? library.fileUri : library.importUri);
+  void computeForLibrary(Library library) {
+    LibraryId id = new LibraryId(library.fileUri);
     T value = computeLibraryValue(id, library);
     registerValue(library.fileUri, null, id, value, library);
   }
diff --git a/pkg/front_end/lib/src/testing/id_testing.dart b/pkg/front_end/lib/src/testing/id_testing.dart
index 6aba9fb..3c49ea0 100644
--- a/pkg/front_end/lib/src/testing/id_testing.dart
+++ b/pkg/front_end/lib/src/testing/id_testing.dart
@@ -214,6 +214,8 @@
             entry;
       }
     }
+    assert(
+        mainTestFile != null, "No 'main.dart' test file found for $testFile.");
   }
 
   String annotatedCode = new File.fromUri(mainTestFile.uri).readAsStringSync();
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index ec92375..68aa64d 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -8,6 +8,7 @@
 import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 import '../api_prototype/terminal_color_support.dart'
     show printDiagnosticMessage;
+import '../base/common.dart';
 import '../fasta/messages.dart' show FormattedMessage;
 import '../fasta/severity.dart' show Severity;
 import '../kernel_generator_impl.dart' show InternalCompilerResult;
@@ -42,8 +43,10 @@
   final String marker;
   final String name;
   final Map<ExperimentalFlag, bool> experimentalFlags;
+  final Uri librariesSpecificationUri;
 
-  const TestConfig(this.marker, this.name, {this.experimentalFlags = const {}});
+  const TestConfig(this.marker, this.name,
+      {this.experimentalFlags = const {}, this.librariesSpecificationUri});
 
   void customizeCompilerOptions(CompilerOptions options) {}
 }
@@ -180,6 +183,7 @@
 /// Creates a test runner for [dataComputer] on [testedConfigs].
 RunTestFunction runTestFor<T>(
     DataComputer<T> dataComputer, List<TestConfig> testedConfigs) {
+  retainDataForTesting = true;
   return (TestData testData,
       {bool testAfterFailures, bool verbose, bool succinct, bool printCode}) {
     return runTest(testData, dataComputer, testedConfigs,
@@ -242,6 +246,13 @@
   };
   options.debugDump = printCode;
   options.experimentalFlags.addAll(config.experimentalFlags);
+  if (config.librariesSpecificationUri != null) {
+    Set<Uri> testFiles =
+        testData.memorySourceFiles.keys.map(createUriForFileName).toSet();
+    if (testFiles.contains(config.librariesSpecificationUri)) {
+      options.librariesSpecificationUri = config.librariesSpecificationUri;
+    }
+  }
   config.customizeCompilerOptions(options);
   InternalCompilerResult compilerResult = await compileScript(
       testData.memorySourceFiles,
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index d32d8f5..0c98653 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -62,7 +62,7 @@
       (Extension extension) => extension.name == extensionName, orElse: () {
     if (required) {
       throw new ArgumentError(
-          "Extension '$extensionName' not found in '$library'.");
+          "Extension '$extensionName' not found in '${library.importUri}'.");
     }
     return null;
   });
@@ -151,7 +151,7 @@
       lookupClassBuilder(compilerResult, cls, required: required);
   MemberBuilder memberBuilder;
   if (classBuilder != null) {
-    if (member is Constructor) {
+    if (member is Constructor || member is Procedure && member.isFactory) {
       memberBuilder = classBuilder.constructors.local[memberName];
     } else if (member is Procedure && member.isSetter) {
       memberBuilder = classBuilder.scope.setters[memberName];
@@ -527,9 +527,6 @@
 /// Returns a textual representation of [descriptor] to be used in testing.
 String extensionMethodDescriptorToText(ExtensionMemberDescriptor descriptor) {
   StringBuffer sb = new StringBuffer();
-  if (descriptor.isExternal) {
-    sb.write('external ');
-  }
   if (descriptor.isStatic) {
     sb.write('static ');
   }
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 34bb332..ccc99a2 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -215,6 +215,7 @@
 ExtensionDeclaresAbstractMember/example: Fail
 ExtensionDeclaresConstructor/example: Fail
 ExtensionDeclaresInstanceField/example: Fail
+ExtensionMemberConflictsWithObjectMember/analyzerCode: Fail
 ExtraneousModifier/part_wrapped_script1: Fail
 ExtraneousModifier/part_wrapped_script2: Fail
 ExtraneousModifier/part_wrapped_script3: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 2782772..e67853d 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -457,8 +457,8 @@
 
 EqualityCannotBeEqualityOperand:
   index: 1
-  template: "An equality expression can't be an operand of another equality expression."
-  tip: "Try re-writing the expression."
+  template: "A comparison expression can't be an operand of another comparison expression."
+  tip: "Try putting parentheses around one of the comparisons."
   analyzerCode: ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
   script:
     - "main() { var b = a < b < c; }"
@@ -703,7 +703,7 @@
 ExternalField:
   index: 50
   template: "Fields can't be declared to be 'external'."
-  tip: "Try removing the keyword 'external'."
+  tip: "Try removing the keyword 'external', or replacing the field by an external getter and/or setter."
   analyzerCode: ParserErrorCode.EXTERNAL_FIELD
   script:
     - "class C { external var f; }"
@@ -926,7 +926,7 @@
   script: "main() sync {}"
 
 InvalidVoid:
-  template: "Type 'void' can't be used here because it isn't a return type."
+  template: "Type 'void' can't be used here."
   tip: "Try removing 'void' keyword or replace it with 'var', 'final', or a type."
   analyzerCode: EXPECTED_TYPE_NAME
   script:
@@ -943,7 +943,7 @@
 
 FieldInitializedOutsideDeclaringClass:
   index: 88
-  template: "A field can only be initialized in it's declaring class"
+  template: "A field can only be initialized in its declaring class"
   tip: "Try passing a value into the superclass constructor, or moving the initialization into the constructor body."
   analyzerCode: ParserErrorCode.FIELD_INITIALIZED_OUTSIDE_DECLARING_CLASS
   script:
@@ -1137,7 +1137,6 @@
 
 BuiltInIdentifierAsType:
   template: "The built-in identifier '#lexeme' can't be used as a type."
-  tip: "Try correcting the name to match an existing type."
   analyzerCode: BUILT_IN_IDENTIFIER_AS_TYPE
 
 BuiltInIdentifierInDeclaration:
@@ -1265,12 +1264,12 @@
 
 ConstFieldWithoutInitializer:
   template: "The const variable '#name' must be initialized."
-  tip: "Try adding an initializer ('= <expression>') to the declaration."
+  tip: "Try adding an initializer ('= expression') to the declaration."
   analyzerCode: CONST_NOT_INITIALIZED
 
 FinalFieldWithoutInitializer:
   template: "The final variable '#name' must be initialized."
-  tip: "Try adding an initializer ('= <expression>') to the declaration."
+  tip: "Try adding an initializer ('= expression') to the declaration."
   analyzerCode: FINAL_NOT_INITIALIZED
 
 MetadataTypeArguments:
@@ -1718,7 +1717,7 @@
 MissingPrefixInDeferredImport:
   index: 30
   template: "Deferred imports should have a prefix."
-  tip: "Try adding a prefix to the import."
+  tip: "Try adding a prefix to the import by adding an 'as' clause."
   analyzerCode: ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT
 
 DeferredAfterPrefix:
@@ -1936,6 +1935,13 @@
   template: "This is the type variable."
   severity: CONTEXT
 
+ExtensionMemberConflictsWithObjectMember:
+  template: "This extension member conflicts with Object member '#name'."
+  script:
+    extension Extension on String {
+      int get noSuchMethod => 42;
+    }
+
 DeclaredMemberConflictsWithInheritedMember:
   template: "Can't declare a member that conflicts with an inherited one."
   analyzerCode: DECLARED_MEMBER_CONFLICTS_WITH_INHERITED
@@ -2781,7 +2787,7 @@
 
 MissingAssignableSelector:
   index: 35
-  template: "Missing selector such as '.<identifier>' or '[0]'."
+  template: "Missing selector such as '.identifier' or '[0]'."
   tip: "Try adding a selector."
   analyzerCode: ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR
   script:
@@ -2833,12 +2839,10 @@
 
 ArgumentTypeNotAssignable:
   template: "The argument type '#type' can't be assigned to the parameter type '#type2'."
-  tip: "Try changing the type of the parameter, or casting the argument to '#type2'."
   analyzerCode: ARGUMENT_TYPE_NOT_ASSIGNABLE
 
 InvalidAssignment:
   template: "A value of type '#type' can't be assigned to a variable of type '#type2'."
-  tip: "Try changing the type of the left hand side, or casting the right hand side to '#type2'."
   analyzerCode: INVALID_ASSIGNMENT
   script: >
     main() {
@@ -3157,7 +3161,7 @@
 
 CantUsePrefixWithNullAware:
   template: "A prefix can't be used with null-aware operators."
-  tip: "It should be safe to remove the '?' as a prefix is never null."
+  tip: "Try replacing '?.' with '.'"
   analyzerCode: PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
   script: |
     import "dart:core" as prefix;
@@ -3418,7 +3422,7 @@
     class C = Object with M;
 
 GenericFunctionTypeUsedAsActualTypeArgument:
-  template: "Unexpected generic function type found in a type argument."
+  template: "A generic function type can't be used as a type argument."
   tip: "Try using a non-generic function type."
   analyzerCode: GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT
   script:
@@ -3434,7 +3438,7 @@
       }
 
 GenericFunctionTypeInferredAsActualTypeArgument:
-  template: "Unexpected generic function type '#type' inferred as a type argument."
+  template: "Generic function type '#type' inferred as a type argument."
   tip: "Try providing a non-generic function type explicitly."
   analyzerCode: GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT
   script:
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect
new file mode 100644
index 0000000..7bf2cde
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect
@@ -0,0 +1,88 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(.)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(.)
+                              listener: handleSend(foo, .)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(baz, expressionContinuation)
+                            listener: handleNoTypeArguments([)
+                            parseArgumentsOpt(baz)
+                              listener: handleNoArguments([)
+                            listener: handleSend(baz, [)
+                      listener: endBinaryExpression(.)
+                      parseArgumentOrIndexStar(baz, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..69fcc2c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
@@ -0,0 +1,99 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(foo, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(foo)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(foo, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(bar, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt(bar)
+                                                listener: handleNoArguments())
+                                              listener: handleSend(bar, ))
+                                        listener: endBinaryExpression(.)
+                                    ensureCloseParen(bar, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: handleNonNullAssertExpression(!)
+                        parsePrimary(., expressionContinuation)
+                          parseSendOrFunctionLiteral(., expressionContinuation)
+                            parseSend(., expressionContinuation)
+                              ensureIdentifier(., expressionContinuation)
+                                listener: handleIdentifier(baz, expressionContinuation)
+                              listener: handleNoTypeArguments([)
+                              parseArgumentsOpt(baz)
+                                listener: handleNoArguments([)
+                              listener: handleSend(baz, [)
+                        listener: endBinaryExpression(.)
+                        parseArgumentOrIndexStar(baz, Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect
new file mode 100644
index 0000000..109f304
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect
@@ -0,0 +1,68 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, obj)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(obj)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(obj, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(obj)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(obj, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect
new file mode 100644
index 0000000..0b43b40
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect
@@ -0,0 +1,83 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, obj)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(obj)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(obj, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(obj)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(obj, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg2, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg2)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg2, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..6c15e07
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
@@ -0,0 +1,114 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                              parseParenthesizedExpression(()
+                                                                parseExpressionInParenthesis(()
+                                                                  parseExpressionInParenthesisRest(()
+                                                                    parseExpression(()
+                                                                      parsePrecedenceExpression((, 1, true)
+                                                                        parseUnaryExpression((, true)
+                                                                          parsePrimary((, expression)
+                                                                            parseSendOrFunctionLiteral((, expression)
+                                                                              parseSend((, expression)
+                                                                                ensureIdentifier((, expression)
+                                                                                  listener: handleIdentifier(obj, expression)
+                                                                                listener: handleNoTypeArguments(!)
+                                                                                parseArgumentsOpt(obj)
+                                                                                  listener: handleNoArguments(!)
+                                                                                listener: handleSend(obj, !)
+                                                                        listener: handleNonNullAssertExpression(!)
+                                                                    ensureCloseParen(!, ()
+                                                                listener: handleParenthesizedExpression(()
+                                                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                                                          parseExpression([)
+                                                            parsePrecedenceExpression([, 1, true)
+                                                              parseUnaryExpression([, true)
+                                                                parsePrimary([, expression)
+                                                                  parseSendOrFunctionLiteral([, expression)
+                                                                    parseSend([, expression)
+                                                                      ensureIdentifier([, expression)
+                                                                        listener: handleIdentifier(arg, expression)
+                                                                      listener: handleNoTypeArguments(])
+                                                                      parseArgumentsOpt(arg)
+                                                                        listener: handleNoArguments(])
+                                                                      listener: handleSend(arg, ])
+                                                          listener: handleIndexedExpression([, ])
+                                                    ensureCloseParen(], ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg2, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg2)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg2, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect
new file mode 100644
index 0000000..f3b48e4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect
@@ -0,0 +1,78 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(.)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(.)
+                              listener: handleSend(foo, .)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..c349f09
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
@@ -0,0 +1,89 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(foo, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(foo)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(foo, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(bar, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt(bar)
+                                                listener: handleNoArguments())
+                                              listener: handleSend(bar, ))
+                                        listener: endBinaryExpression(.)
+                                    ensureCloseParen(bar, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: handleNonNullAssertExpression(!)
+                        parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect
new file mode 100644
index 0000000..89095e5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect
@@ -0,0 +1,79 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(foo, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..4e8d872
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
@@ -0,0 +1,100 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseSendOrFunctionLiteral((, expression)
+                                                              parseSend((, expression)
+                                                                ensureIdentifier((, expression)
+                                                                  listener: handleIdentifier(foo, expression)
+                                                                listener: handleNoTypeArguments(!)
+                                                                parseArgumentsOpt(foo)
+                                                                  listener: handleNoArguments(!)
+                                                                listener: handleSend(foo, !)
+                                                        listener: handleNonNullAssertExpression(!)
+                                                    ensureCloseParen(!, ()
+                                                listener: handleParenthesizedExpression(()
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(bar, expressionContinuation)
+                                              listener: handleNoTypeArguments(!)
+                                              parseArgumentsOpt(bar)
+                                                listener: handleNoArguments(!)
+                                              listener: handleSend(bar, !)
+                                        listener: endBinaryExpression(.)
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect
new file mode 100644
index 0000000..c6b3abd
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect
@@ -0,0 +1,93 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(.)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(.)
+                              listener: handleSend(foo, .)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg2, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg2)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg2, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..1f1f0bf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
@@ -0,0 +1,124 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                              parseParenthesizedExpression(()
+                                                                parseExpressionInParenthesis(()
+                                                                  parseExpressionInParenthesisRest(()
+                                                                    parseExpression(()
+                                                                      parsePrecedenceExpression((, 1, true)
+                                                                        parseUnaryExpression((, true)
+                                                                          parsePrimary((, expression)
+                                                                            parseSendOrFunctionLiteral((, expression)
+                                                                              parseSend((, expression)
+                                                                                ensureIdentifier((, expression)
+                                                                                  listener: handleIdentifier(foo, expression)
+                                                                                listener: handleNoTypeArguments(.)
+                                                                                parseArgumentsOpt(foo)
+                                                                                  listener: handleNoArguments(.)
+                                                                                listener: handleSend(foo, .)
+                                                                        parsePrimary(., expressionContinuation)
+                                                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                                                            parseSend(., expressionContinuation)
+                                                                              ensureIdentifier(., expressionContinuation)
+                                                                                listener: handleIdentifier(bar, expressionContinuation)
+                                                                              listener: handleNoTypeArguments(!)
+                                                                              parseArgumentsOpt(bar)
+                                                                                listener: handleNoArguments(!)
+                                                                              listener: handleSend(bar, !)
+                                                                        listener: endBinaryExpression(.)
+                                                                        listener: handleNonNullAssertExpression(!)
+                                                                    ensureCloseParen(!, ()
+                                                                listener: handleParenthesizedExpression(()
+                                                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                                                          parseExpression([)
+                                                            parsePrecedenceExpression([, 1, true)
+                                                              parseUnaryExpression([, true)
+                                                                parsePrimary([, expression)
+                                                                  parseSendOrFunctionLiteral([, expression)
+                                                                    parseSend([, expression)
+                                                                      ensureIdentifier([, expression)
+                                                                        listener: handleIdentifier(arg, expression)
+                                                                      listener: handleNoTypeArguments(])
+                                                                      parseArgumentsOpt(arg)
+                                                                        listener: handleNoArguments(])
+                                                                      listener: handleSend(arg, ])
+                                                          listener: handleIndexedExpression([, ])
+                                                    ensureCloseParen(], ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg2, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg2)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg2, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect
new file mode 100644
index 0000000..795f82d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect
@@ -0,0 +1,94 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(foo, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg2, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg2)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg2, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..41a6cb6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
@@ -0,0 +1,135 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                              parseParenthesizedExpression(()
+                                                                parseExpressionInParenthesis(()
+                                                                  parseExpressionInParenthesisRest(()
+                                                                    parseExpression(()
+                                                                      parsePrecedenceExpression((, 1, true)
+                                                                        parseUnaryExpression((, true)
+                                                                          parsePrimary((, expression)
+                                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                                              parseParenthesizedExpression(()
+                                                                                parseExpressionInParenthesis(()
+                                                                                  parseExpressionInParenthesisRest(()
+                                                                                    parseExpression(()
+                                                                                      parsePrecedenceExpression((, 1, true)
+                                                                                        parseUnaryExpression((, true)
+                                                                                          parsePrimary((, expression)
+                                                                                            parseSendOrFunctionLiteral((, expression)
+                                                                                              parseSend((, expression)
+                                                                                                ensureIdentifier((, expression)
+                                                                                                  listener: handleIdentifier(foo, expression)
+                                                                                                listener: handleNoTypeArguments(!)
+                                                                                                parseArgumentsOpt(foo)
+                                                                                                  listener: handleNoArguments(!)
+                                                                                                listener: handleSend(foo, !)
+                                                                                        listener: handleNonNullAssertExpression(!)
+                                                                                    ensureCloseParen(!, ()
+                                                                                listener: handleParenthesizedExpression(()
+                                                                        parsePrimary(., expressionContinuation)
+                                                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                                                            parseSend(., expressionContinuation)
+                                                                              ensureIdentifier(., expressionContinuation)
+                                                                                listener: handleIdentifier(bar, expressionContinuation)
+                                                                              listener: handleNoTypeArguments(!)
+                                                                              parseArgumentsOpt(bar)
+                                                                                listener: handleNoArguments(!)
+                                                                              listener: handleSend(bar, !)
+                                                                        listener: endBinaryExpression(.)
+                                                                        listener: handleNonNullAssertExpression(!)
+                                                                    ensureCloseParen(!, ()
+                                                                listener: handleParenthesizedExpression(()
+                                                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                                                          parseExpression([)
+                                                            parsePrecedenceExpression([, 1, true)
+                                                              parseUnaryExpression([, true)
+                                                                parsePrimary([, expression)
+                                                                  parseSendOrFunctionLiteral([, expression)
+                                                                    parseSend([, expression)
+                                                                      ensureIdentifier([, expression)
+                                                                        listener: handleIdentifier(arg, expression)
+                                                                      listener: handleNoTypeArguments(])
+                                                                      parseArgumentsOpt(arg)
+                                                                        listener: handleNoArguments(])
+                                                                      listener: handleSend(arg, ])
+                                                          listener: handleIndexedExpression([, ])
+                                                    ensureCloseParen(], ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg2, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg2)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg2, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..0f8729a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
@@ -0,0 +1,79 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(obj, expression)
+                                                listener: handleNoTypeArguments(!)
+                                                parseArgumentsOpt(obj)
+                                                  listener: handleNoArguments(!)
+                                                listener: handleSend(obj, !)
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/test/extensions/data/as_show/lib.dart b/pkg/front_end/test/extensions/data/as_show/lib.dart
new file mode 100644
index 0000000..e89ef0c
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/lib.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: scope=[Extension1]*/
+
+/*class: Extension1:
+ builder-name=Extension1,
+ builder-onType=String,
+ extension-members=[
+  method1=Extension1|method1,
+  tearoff method1=Extension1|get#method1],
+ extension-name=Extension1,
+ extension-onType=String
+*/
+extension Extension1 on String {
+  /*member: Extension1|method1:
+   builder-name=method1,
+   builder-params=[#this],
+   member-name=Extension1|method1,
+   member-params=[#this]
+  */
+  method1() {}
+
+  /*member: Extension1|get#method1:
+   builder-name=method1,
+   builder-params=[#this],
+   member-name=Extension1|get#method1,
+   member-params=[#this]*/
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/as_show/libraries.json b/pkg/front_end/test/extensions/data/as_show/libraries.json
new file mode 100644
index 0000000..7a584cb
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/libraries.json
@@ -0,0 +1,9 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "uri": "origin.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/test/extensions/data/as_show/main.dart b/pkg/front_end/test/extensions/data/as_show/main.dart
new file mode 100644
index 0000000..2a7d2d1
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/main.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: scope=[lib.dart.Extension1,origin.dart.Extension2]*/
+
+import 'lib.dart' as lib1;
+import 'lib.dart' show Extension1;
+
+// ignore: uri_does_not_exist
+import 'dart:test' as lib2;
+// ignore: uri_does_not_exist
+import 'dart:test' show Extension2;
+
+main() {
+  "".method1();
+  Extension1("").method1();
+  "".method2();
+  Extension2("").method2();
+}
diff --git a/pkg/front_end/test/extensions/data/as_show/origin.dart b/pkg/front_end/test/extensions/data/as_show/origin.dart
new file mode 100644
index 0000000..1b36bb9
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/origin.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: scope=[Extension2]*/
+
+/*class: Extension2:
+ builder-name=Extension2,
+ builder-onType=String,
+ extension-members=[
+  method2=Extension2|method2,
+  tearoff method2=Extension2|get#method2],
+ extension-name=Extension2,
+ extension-onType=String
+*/
+extension Extension2 on String {
+/*member: Extension2|method2:
+   builder-name=method2,
+   builder-params=[#this],
+   member-name=Extension2|method2,
+   member-params=[#this]
+  */
+method2() {}
+
+/*member: Extension2|get#method2:
+   builder-name=method2,
+   builder-params=[#this],
+   member-name=Extension2|get#method2,
+   member-params=[#this]*/
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/patching/libraries.json b/pkg/front_end/test/extensions/data/patching/libraries.json
new file mode 100644
index 0000000..a697508
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/libraries.json
@@ -0,0 +1,12 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "patches": [
+          "patch.dart"
+        ],
+        "uri": "origin.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/test/extensions/data/patching/main.dart b/pkg/front_end/test/extensions/data/patching/main.dart
new file mode 100644
index 0000000..9599059
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/main.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: scope=[origin.dart.Extension,origin.dart.GenericExtension]*/
+
+// ignore: uri_does_not_exist
+import 'dart:test';
+
+main() {
+  "".instanceMethod();
+  "".genericInstanceMethod<int>(0);
+  "".instanceProperty = "".instanceProperty;
+  Extension.staticMethod();
+  Extension.genericStaticMethod<int>(0);
+  Extension.staticProperty = Extension.staticProperty;
+  true.instanceMethod();
+  true.genericInstanceMethod<int>(0);
+  true.instanceProperty = true.instanceProperty;
+  GenericExtension.staticMethod();
+  GenericExtension.genericStaticMethod<int>(0);
+  GenericExtension.staticProperty = GenericExtension.staticProperty;
+}
diff --git a/pkg/front_end/test/extensions/data/patching/origin.dart b/pkg/front_end/test/extensions/data/patching/origin.dart
new file mode 100644
index 0000000..1a5b69e
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/origin.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: scope=[Extension,GenericExtension]*/
+
+/*class: Extension:
+ builder-name=Extension,
+ builder-onType=String,
+ extension-members=[
+  genericInstanceMethod=Extension|genericInstanceMethod,
+  getter instanceProperty=Extension|get#instanceProperty,
+  instanceMethod=Extension|instanceMethod,
+  setter instanceProperty=Extension|set#instanceProperty,
+  static genericStaticMethod=Extension|genericStaticMethod,
+  static getter staticProperty=Extension|staticProperty,
+  static setter staticProperty=Extension|staticProperty=,
+  static staticMethod=Extension|staticMethod,
+  tearoff genericInstanceMethod=Extension|get#genericInstanceMethod,
+  tearoff instanceMethod=Extension|get#instanceMethod,
+ ],
+ extension-name=Extension,
+ extension-onType=String
+*/
+extension Extension on String {
+  /*member: Extension|get#instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   member-name=Extension|get#instanceMethod,
+   member-params=[#this]
+  */
+  external int instanceMethod();
+
+  /*member: Extension|get#genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T],
+   member-name=Extension|get#genericInstanceMethod,
+   member-params=[#this]
+  */
+  external T genericInstanceMethod<T>(T t);
+
+  external static int staticMethod();
+
+  external static T genericStaticMethod<T>(T t);
+
+  external int get instanceProperty;
+
+  external void set instanceProperty(int value);
+
+  external static int get staticProperty;
+
+  external static void set staticProperty(int value);
+}
+
+/*class: GenericExtension:
+ builder-name=GenericExtension,
+ builder-onType=T,
+ builder-type-params=[T],
+ extension-members=[
+  genericInstanceMethod=GenericExtension|genericInstanceMethod,
+  getter instanceProperty=GenericExtension|get#instanceProperty,
+  instanceMethod=GenericExtension|instanceMethod,
+  setter instanceProperty=GenericExtension|set#instanceProperty,
+  static genericStaticMethod=GenericExtension|genericStaticMethod,
+  static getter staticProperty=GenericExtension|staticProperty,
+  static setter staticProperty=GenericExtension|staticProperty=,
+  static staticMethod=GenericExtension|staticMethod,
+  tearoff genericInstanceMethod=GenericExtension|get#genericInstanceMethod,
+  tearoff instanceMethod=GenericExtension|get#instanceMethod
+  ],
+ extension-name=GenericExtension,
+ extension-onType=T,
+ extension-type-params=[T]
+*/
+extension GenericExtension<T> on T {
+  /*member: GenericExtension|get#instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   builder-type-params=[T],
+   member-name=GenericExtension|get#instanceMethod,
+   member-params=[#this],
+   member-type-params=[T]
+  */
+  external int instanceMethod();
+
+  /*member: GenericExtension|get#genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T,T],
+   member-name=GenericExtension|get#genericInstanceMethod,
+   member-params=[#this],
+   member-type-params=[#T]
+  */
+  external T genericInstanceMethod<T>(T t);
+
+  external static int staticMethod();
+
+  external static T genericStaticMethod<T>(T t);
+
+  external int get instanceProperty;
+
+  external void set instanceProperty(int value);
+
+  external static int get staticProperty;
+
+  external static void set staticProperty(int value);
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/patching/patch.dart b/pkg/front_end/test/extensions/data/patching/patch.dart
new file mode 100644
index 0000000..32edfc4
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/patch.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+extension Extension on String {
+  /*member: Extension|instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   member-name=Extension|instanceMethod,
+   member-params=[#this]
+  */
+  @patch
+  int instanceMethod() => 42;
+
+  /*member: Extension|genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T],
+   member-name=Extension|genericInstanceMethod,
+   member-params=[#this,t],
+   member-type-params=[T]
+  */
+  @patch
+  T genericInstanceMethod<T>(T t) => t;
+
+  /*member: Extension|staticMethod:
+   builder-name=staticMethod,
+   member-name=Extension|staticMethod
+  */
+  @patch
+  static int staticMethod() => 87;
+
+  /*member: Extension|genericStaticMethod:
+   builder-name=genericStaticMethod,
+   builder-params=[t],
+   builder-type-params=[T],
+   member-name=Extension|genericStaticMethod,
+   member-params=[t],
+   member-type-params=[T]
+  */
+  @patch
+  static T genericStaticMethod<T>(T t) => t;
+
+  /*member: Extension|get#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this],
+   member-name=Extension|get#instanceProperty,
+   member-params=[#this]
+  */
+  @patch
+  int get instanceProperty => 123;
+
+  /*member: Extension|set#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this,value],
+   member-name=Extension|set#instanceProperty,
+   member-params=[#this,value]
+  */
+  @patch
+  void set instanceProperty(int value) {}
+
+  /*member: Extension|staticProperty:
+   builder-name=staticProperty,
+   member-name=Extension|staticProperty
+  */
+  @patch
+  static int get staticProperty => 237;
+
+  /*member: Extension|staticProperty=:
+   builder-name=staticProperty,
+   builder-params=[value],
+   member-name=Extension|staticProperty=,
+   member-params=[value]
+  */
+  @patch
+  static void set staticProperty(int value) {}
+}
+
+
+@patch
+extension GenericExtension<T> on T {
+  /*member: GenericExtension|instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   builder-type-params=[T],
+   member-name=GenericExtension|instanceMethod,
+   member-params=[#this],
+   member-type-params=[T]
+  */
+  @patch
+  int instanceMethod() => 42;
+
+  /*member: GenericExtension|genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T,T],
+   member-name=GenericExtension|genericInstanceMethod,
+   member-params=[#this,t],
+   member-type-params=[#T,T]
+  */
+  @patch
+  T genericInstanceMethod<T>(T t) => t;
+
+  /*member: GenericExtension|staticMethod:
+   builder-name=staticMethod,
+   member-name=GenericExtension|staticMethod
+  */
+  @patch
+  static int staticMethod() => 87;
+
+  /*member: GenericExtension|genericStaticMethod:
+   builder-name=genericStaticMethod,
+   builder-params=[t],
+   builder-type-params=[T],
+   member-name=GenericExtension|genericStaticMethod,
+   member-params=[t],
+   member-type-params=[T]
+  */
+  @patch
+  static T genericStaticMethod<T>(T t) => t;
+
+  /*member: GenericExtension|get#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this],
+   builder-type-params=[T],
+   member-name=GenericExtension|get#instanceProperty,
+   member-params=[#this],
+   member-type-params=[T]
+  */
+  @patch
+  int get instanceProperty => 123;
+
+  /*member: GenericExtension|set#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this,value],
+   builder-type-params=[T],
+   member-name=GenericExtension|set#instanceProperty,
+   member-params=[#this,value],
+   member-type-params=[T]
+  */
+  @patch
+  void set instanceProperty(int value) {}
+
+  /*member: GenericExtension|staticProperty:
+   builder-name=staticProperty,
+   member-name=GenericExtension|staticProperty
+  */
+  @patch
+  static int get staticProperty => 237;
+
+  /*member: GenericExtension|staticProperty=:
+   builder-name=staticProperty,
+   builder-params=[value],
+   member-name=GenericExtension|staticProperty=,
+   member-params=[value]
+  */
+  @patch
+  static void set staticProperty(int value) {}
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/extensions_test.dart b/pkg/front_end/test/extensions/extensions_test.dart
index 33e8fb4..880d249 100644
--- a/pkg/front_end/test/extensions/extensions_test.dart
+++ b/pkg/front_end/test/extensions/extensions_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+import 'package:front_end/src/api_prototype/experimental_flags.dart'
+    show ExperimentalFlag;
 import 'package:front_end/src/fasta/builder/builder.dart';
 import 'package:front_end/src/fasta/builder/extension_builder.dart';
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
@@ -22,8 +24,11 @@
       supportedMarkers: sharedMarkers,
       createUriForFileName: createUriForFileName,
       onFailure: onFailure,
-      runTest: runTestFor(
-          const ExtensionsDataComputer(), [cfeExtensionMethodsConfig]));
+      runTest: runTestFor(const ExtensionsDataComputer(), [
+        new TestConfig(cfeMarker, 'cfe with extension methods',
+            experimentalFlags: const {ExperimentalFlag.extensionMethods: true},
+            librariesSpecificationUri: createUriForFileName('libraries.json'))
+      ]));
 }
 
 class ExtensionsDataComputer extends DataComputer<Features> {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 1908a65..c92c98e 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -8,6 +8,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/type_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -691,13 +692,17 @@
   void test_unknown_at_bottom() {
     var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
     var env = _makeEnv();
-    expect(env.isSubtypeOf(unknownType, A), isTrue);
+    expect(
+        env.isSubtypeOf(unknownType, A, SubtypeCheckMode.ignoringNullabilities),
+        isTrue);
   }
 
   void test_unknown_at_top() {
     var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
     var env = _makeEnv();
-    expect(env.isSubtypeOf(A, unknownType), isTrue);
+    expect(
+        env.isSubtypeOf(A, unknownType, SubtypeCheckMode.ignoringNullabilities),
+        isTrue);
   }
 
   Class _addClass(Class c) {
diff --git a/pkg/front_end/test/fasta/types/fasta_types_test.dart b/pkg/front_end/test/fasta/types/fasta_types_test.dart
index f4dc886..5d3659ad 100644
--- a/pkg/front_end/test/fasta/types/fasta_types_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_types_test.dart
@@ -26,6 +26,7 @@
     show ClassHierarchyBuilder, ClassBuilder;
 
 import "package:front_end/src/fasta/ticker.dart" show Ticker;
+import 'package:kernel/type_environment.dart';
 
 import "kernel_type_parser.dart" show KernelEnvironment, KernelFromParsedType;
 
@@ -73,7 +74,8 @@
   }
 
   bool isSubtypeImpl(DartType subtype, DartType supertype) {
-    return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+    return hierarchy.types.isSubtypeOfKernel(
+        subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
   }
 
   KernelEnvironment extend(String typeParameters) {
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
index c8af98e..d03b95d 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
@@ -12,7 +12,8 @@
 
 import "package:kernel/text/ast_to_text.dart" show Printer;
 
-import "package:kernel/type_environment.dart" show TypeEnvironment;
+import "package:kernel/type_environment.dart"
+    show SubtypeCheckMode, TypeEnvironment;
 
 import "kernel_type_parser.dart"
     show KernelEnvironment, KernelFromParsedType, parseLibrary;
@@ -42,7 +43,7 @@
 
 typedef Typedef<T extends self::Object* = dynamic> = <S extends self::Object* = dynamic>(T*) →* S*;
 typedef VoidFunction = () →* void;
-typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>*, self::List<self::Object>*, self::Comparable<dynamic>*, (<BottomType>) →* void, () →* self::Comparable<dynamic>*>;
+typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>, self::List<self::Object>, self::Comparable<dynamic>, (<BottomType>) → void, () → self::Comparable<dynamic>>;
 typedef Id<T extends self::Object* = dynamic> = T*;
 typedef TestSorting = ({a: self::int, b: self::int, c: self::int}) →* void;
 class Object {
@@ -71,13 +72,13 @@
 }
 class bool extends self::Object {
 }
-class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>*, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>*, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>*, X extends (self::DefaultTypes::W) → void = (<BottomType>) →* void, Y extends () → self::DefaultTypes::W = () →* self::Comparable<dynamic>*> extends self::Object {
+class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>, X extends (self::DefaultTypes::W) → void = (<BottomType>) → void, Y extends () → self::DefaultTypes::W = () → self::Comparable<dynamic>> extends self::Object {
 }
 class Super extends self::Object implements self::Comparable<self::Sub> {
 }
 class Sub extends self::Super {
 }
-class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>*> extends self::Object {
+class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>> extends self::Object {
 }
 class MixinApplication = self::Object with self::FBound<self::MixinApplication> {
 }
@@ -119,8 +120,8 @@
   }
 
   bool isSubtypeImpl(DartType subtype, DartType supertype) {
-    return new TypeEnvironment(coreTypes, hierarchy)
-        .isSubtypeOf(subtype, supertype);
+    return new TypeEnvironment(coreTypes, hierarchy).isSubtypeOf(
+        subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
   }
 
   KernelEnvironment extend(String typeParameters) {
diff --git a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
index dc3e3f8..c46d75a 100644
--- a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
+++ b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
@@ -14,7 +14,8 @@
 
 import "package:kernel/target/targets.dart" show NoneTarget, TargetFlags;
 
-import "package:kernel/type_environment.dart" show TypeEnvironment;
+import "package:kernel/type_environment.dart"
+    show SubtypeCheckMode, TypeEnvironment;
 
 import "kernel_type_parser.dart"
     show KernelEnvironment, KernelFromParsedType, parseLibrary;
@@ -101,7 +102,8 @@
 void performChecks(List<SubtypeCheck> checks, TypeEnvironment environment) {
   for (int i = 0; i < checks.length; i++) {
     SubtypeCheck check = checks[i];
-    bool isSubtype = environment.isSubtypeOf(check.s, check.t);
+    bool isSubtype = environment.isSubtypeOf(
+        check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
     if (isSubtype != check.isSubtype) {
       throw "Check failed: $check";
     }
@@ -112,7 +114,8 @@
     List<SubtypeCheck> checks, ClassHierarchyBuilder hierarchy) {
   for (int i = 0; i < checks.length; i++) {
     SubtypeCheck check = checks[i];
-    bool isSubtype = hierarchy.types.isSubtypeOfKernel(check.s, check.t);
+    bool isSubtype = hierarchy.types.isSubtypeOfKernel(
+        check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
     if (isSubtype != check.isSubtype) {
       throw "Check failed: $check";
     }
diff --git a/pkg/front_end/test/id_testing/id_testing_test.dart b/pkg/front_end/test/id_testing/id_testing_test.dart
index 07d99ba..92a4fb5 100644
--- a/pkg/front_end/test/id_testing/id_testing_test.dart
+++ b/pkg/front_end/test/id_testing/id_testing_test.dart
@@ -58,7 +58,7 @@
       Library library, Map<Id, ActualData<String>> actualMap,
       {bool verbose}) {
     new IdTestingDataExtractor(compilerResult, actualMap)
-        .computeForLibrary(library, useFileUri: true);
+        .computeForLibrary(library);
   }
 
   @override
diff --git a/pkg/front_end/test/language_versioning/language_versioning_test.dart b/pkg/front_end/test/language_versioning/language_versioning_test.dart
index 691df94..a387f9a 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_test.dart
@@ -52,7 +52,7 @@
       Library library, Map<Id, ActualData<String>> actualMap,
       {bool verbose}) {
     new LanguageVersioningDataExtractor(compilerResult, actualMap)
-        .computeForLibrary(library, useFileUri: true);
+        .computeForLibrary(library);
   }
 
   @override
diff --git a/pkg/front_end/test/parser_test.dart b/pkg/front_end/test/parser_test.dart
index 3c6cffb..9daee4d 100644
--- a/pkg/front_end/test/parser_test.dart
+++ b/pkg/front_end/test/parser_test.dart
@@ -31,6 +31,8 @@
 
 import 'parser_test_listener.dart' show ParserTestListener;
 
+import 'parser_test_parser.dart' show TestParser;
+
 const String EXPECTATIONS = '''
 [
   {
@@ -58,17 +60,18 @@
   Context(this.updateExpectations);
 
   final List<Step> steps = const <Step>[
-    const ParserStep(),
+    const ListenerStep(),
+    const IntertwinedStep(),
   ];
 
   final ExpectationSet expectationSet =
       new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
 }
 
-class ParserStep extends Step<TestDescription, TestDescription, Context> {
-  const ParserStep();
+class ListenerStep extends Step<TestDescription, TestDescription, Context> {
+  const ListenerStep();
 
-  String get name => "parser";
+  String get name => "listener";
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) async {
@@ -94,3 +97,43 @@
         ".expect", "${parserTestListener.sb}", description.uri, description);
   }
 }
+
+class IntertwinedStep extends Step<TestDescription, TestDescription, Context> {
+  const IntertwinedStep();
+
+  String get name => "intertwined";
+
+  Future<Result<TestDescription>> run(
+      TestDescription description, Context context) async {
+    File f = new File.fromUri(description.uri);
+    List<int> rawBytes = f.readAsBytesSync();
+
+    Uint8List bytes = new Uint8List(rawBytes.length + 1);
+    bytes.setRange(0, rawBytes.length, rawBytes);
+
+    Utf8BytesScanner scanner =
+        new Utf8BytesScanner(bytes, includeComments: true);
+    Token firstToken = scanner.tokenize();
+
+    if (firstToken == null) {
+      return crash(description, StackTrace.current);
+    }
+
+    ParserTestListener2 parserTestListener = new ParserTestListener2();
+    TestParser parser = new TestParser(parserTestListener);
+    parserTestListener.parser = parser;
+    parser.sb = parserTestListener.sb;
+    parser.parseUnit(firstToken);
+
+    return context.match<TestDescription>(
+        ".intertwined.expect", "${parser.sb}", description.uri, description);
+  }
+}
+
+class ParserTestListener2 extends ParserTestListener {
+  TestParser parser;
+
+  void doPrint(String s) {
+    sb.writeln(("  " * parser.indent) + "listener: " + s);
+  }
+}
diff --git a/pkg/front_end/test/parser_test_listener_creator.dart b/pkg/front_end/test/parser_test_listener_creator.dart
index 1d625bf..35851e7 100644
--- a/pkg/front_end/test/parser_test_listener_creator.dart
+++ b/pkg/front_end/test/parser_test_listener_creator.dart
@@ -11,8 +11,17 @@
 import 'package:front_end/src/fasta/parser/member_kind.dart';
 import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart';
 import 'package:front_end/src/scanner/token.dart';
+import 'package:dart_style/dart_style.dart' show DartFormatter;
 
-main() {
+StringSink out;
+
+main(List<String> args) {
+  if (args.contains("--stdout")) {
+    out = stdout;
+  } else {
+    out = new StringBuffer();
+  }
+
   File f = new File.fromUri(
       Platform.script.resolve("../lib/src/fasta/parser/listener.dart"));
   List<int> rawBytes = f.readAsBytesSync();
@@ -23,7 +32,7 @@
   Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
   Token firstToken = scanner.tokenize();
 
-  print("""
+  out.write("""
 // Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -47,15 +56,17 @@
   void doPrint(String s) {
     sb.writeln(("  " * indent) + s);
   }
-  """);
+""");
 
   ParserCreatorListener listener = new ParserCreatorListener();
   ClassMemberParser parser = new ClassMemberParser(listener);
   parser.parseUnit(firstToken);
 
-  print("""
+  out.writeln("}");
+
+  if (out is StringBuffer) {
+    stdout.write(new DartFormatter().format("$out"));
   }
-  """);
 }
 
 class ParserCreatorListener extends Listener {
@@ -79,13 +90,14 @@
   void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
     if (insideListenerClass) {
+      out.write("  ");
       Token token = beginToken;
       Token latestToken;
       while (true) {
         if (latestToken != null && latestToken.charEnd < token.charOffset) {
-          stdout.write(" ");
+          out.write(" ");
         }
-        stdout.write(token.lexeme);
+        out.write(token.lexeme);
         if ((token is BeginToken &&
                 token.type == TokenType.OPEN_CURLY_BRACKET) ||
             token is SimpleToken && token.type == TokenType.FUNCTION) {
@@ -99,29 +111,29 @@
       }
 
       if (token is SimpleToken && token.type == TokenType.FUNCTION) {
-        stdout.write(" null;");
+        out.write(" null;");
       } else {
-        stdout.write("\n");
+        out.write("\n    ");
         if (currentMethodName.startsWith("end")) {
-          stdout.write("indent--;\n");
+          out.write("indent--;\n    ");
         }
-        stdout.write("doPrint('$currentMethodName(");
+        out.write("doPrint('$currentMethodName(");
         String separator = "";
         for (int i = 0; i < parameters.length; i++) {
-          stdout.write(separator);
-          stdout.write(r"''$");
-          stdout.write(parameters[i]);
+          out.write(separator);
+          out.write(r"' '$");
+          out.write(parameters[i]);
           separator = ", ";
         }
-        stdout.write(")');\n");
+        out.write(")');\n  ");
 
         if (currentMethodName.startsWith("begin")) {
-          stdout.write("indent++;\n");
+          out.write("  indent++;\n  ");
         }
 
-        stdout.write("}");
+        out.write("}");
       }
-      stdout.write("\n\n");
+      out.write("\n\n");
     }
     parameters.clear();
     currentMethodName = null;
diff --git a/pkg/front_end/test/parser_test_parser.dart b/pkg/front_end/test/parser_test_parser.dart
new file mode 100644
index 0000000..6d87b69
--- /dev/null
+++ b/pkg/front_end/test/parser_test_parser.dart
@@ -0,0 +1,2091 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/fasta/parser/listener.dart' show Listener;
+import 'package:front_end/src/fasta/parser/parser.dart' show Parser;
+import 'package:front_end/src/scanner/token.dart';
+import 'package:front_end/src/fasta/fasta_codes.dart';
+import 'package:front_end/src/fasta/scanner.dart';
+import 'package:front_end/src/fasta/parser/assert.dart';
+import 'package:front_end/src/fasta/parser/declaration_kind.dart';
+import 'package:front_end/src/fasta/parser/directive_context.dart';
+import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fasta/parser/identifier_context.dart';
+import 'package:front_end/src/fasta/parser/member_kind.dart';
+import 'package:front_end/src/fasta/parser/token_stream_rewriter.dart';
+import 'package:front_end/src/fasta/parser/type_info.dart';
+
+// THIS FILE IS AUTO GENERATED BY 'test/parser_test_parser_creator.dart'
+
+class TestParser extends Parser {
+  TestParser(Listener listener) : super(listener);
+
+  int indent = 0;
+  StringBuffer sb = new StringBuffer();
+
+  void doPrint(String s) {
+    sb.writeln(("  " * indent) + s);
+  }
+
+  Uri get uri {
+    doPrint('uri()');
+    indent++;
+    var result = super.uri;
+    indent--;
+    return result;
+  }
+
+  TokenStreamRewriter get rewriter {
+    doPrint('rewriter()');
+    indent++;
+    var result = super.rewriter;
+    indent--;
+    return result;
+  }
+
+  bool get inGenerator {
+    doPrint('inGenerator()');
+    indent++;
+    var result = super.inGenerator;
+    indent--;
+    return result;
+  }
+
+  bool get inAsync {
+    doPrint('inAsync()');
+    indent++;
+    var result = super.inAsync;
+    indent--;
+    return result;
+  }
+
+  bool get inPlainSync {
+    doPrint('inPlainSync()');
+    indent++;
+    var result = super.inPlainSync;
+    indent--;
+    return result;
+  }
+
+  bool get isBreakAllowed {
+    doPrint('isBreakAllowed()');
+    indent++;
+    var result = super.isBreakAllowed;
+    indent--;
+    return result;
+  }
+
+  bool get isContinueAllowed {
+    doPrint('isContinueAllowed()');
+    indent++;
+    var result = super.isContinueAllowed;
+    indent--;
+    return result;
+  }
+
+  bool get isContinueWithLabelAllowed {
+    doPrint('isContinueWithLabelAllowed()');
+    indent++;
+    var result = super.isContinueWithLabelAllowed;
+    indent--;
+    return result;
+  }
+
+  Token parseUnit(Token token) {
+    doPrint('parseUnit(' '$token)');
+    indent++;
+    var result = super.parseUnit(token);
+    indent--;
+    return result;
+  }
+
+  Token parseDirectives(Token token) {
+    doPrint('parseDirectives(' '$token)');
+    indent++;
+    var result = super.parseDirectives(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTopLevelDeclaration(Token token) {
+    doPrint('parseTopLevelDeclaration(' '$token)');
+    indent++;
+    var result = super.parseTopLevelDeclaration(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTopLevelDeclarationImpl(
+      Token token, DirectiveContext directiveState) {
+    doPrint('parseTopLevelDeclarationImpl(' '$token, ' '$directiveState)');
+    indent++;
+    var result = super.parseTopLevelDeclarationImpl(token, directiveState);
+    indent--;
+    return result;
+  }
+
+  Token parseClassDeclarationModifiers(Token start, Token keyword) {
+    doPrint('parseClassDeclarationModifiers(' '$start, ' '$keyword)');
+    indent++;
+    var result = super.parseClassDeclarationModifiers(start, keyword);
+    indent--;
+    return result;
+  }
+
+  void parseTopLevelKeywordModifiers(Token start, Token keyword) {
+    doPrint('parseTopLevelKeywordModifiers(' '$start, ' '$keyword)');
+    indent++;
+    var result = super.parseTopLevelKeywordModifiers(start, keyword);
+    indent--;
+    return result;
+  }
+
+  void reportTopLevelModifierError(Token modifier, Token afterModifiers) {
+    doPrint('reportTopLevelModifierError(' '$modifier, ' '$afterModifiers)');
+    indent++;
+    var result = super.reportTopLevelModifierError(modifier, afterModifiers);
+    indent--;
+    return result;
+  }
+
+  Token parseTopLevelKeywordDeclaration(
+      Token start, Token keyword, DirectiveContext directiveState) {
+    doPrint('parseTopLevelKeywordDeclaration('
+        '$start, '
+        '$keyword, '
+        '$directiveState)');
+    indent++;
+    var result =
+        super.parseTopLevelKeywordDeclaration(start, keyword, directiveState);
+    indent--;
+    return result;
+  }
+
+  Token parseLibraryName(Token libraryKeyword) {
+    doPrint('parseLibraryName(' '$libraryKeyword)');
+    indent++;
+    var result = super.parseLibraryName(libraryKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseImportPrefixOpt(Token token) {
+    doPrint('parseImportPrefixOpt(' '$token)');
+    indent++;
+    var result = super.parseImportPrefixOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseImport(Token importKeyword) {
+    doPrint('parseImport(' '$importKeyword)');
+    indent++;
+    var result = super.parseImport(importKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseImportRecovery(Token token) {
+    doPrint('parseImportRecovery(' '$token)');
+    indent++;
+    var result = super.parseImportRecovery(token);
+    indent--;
+    return result;
+  }
+
+  Token parseConditionalUriStar(Token token) {
+    doPrint('parseConditionalUriStar(' '$token)');
+    indent++;
+    var result = super.parseConditionalUriStar(token);
+    indent--;
+    return result;
+  }
+
+  Token parseConditionalUri(Token token) {
+    doPrint('parseConditionalUri(' '$token)');
+    indent++;
+    var result = super.parseConditionalUri(token);
+    indent--;
+    return result;
+  }
+
+  Token parseDottedName(Token token) {
+    doPrint('parseDottedName(' '$token)');
+    indent++;
+    var result = super.parseDottedName(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExport(Token exportKeyword) {
+    doPrint('parseExport(' '$exportKeyword)');
+    indent++;
+    var result = super.parseExport(exportKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseCombinatorStar(Token token) {
+    doPrint('parseCombinatorStar(' '$token)');
+    indent++;
+    var result = super.parseCombinatorStar(token);
+    indent--;
+    return result;
+  }
+
+  Token parseHide(Token token) {
+    doPrint('parseHide(' '$token)');
+    indent++;
+    var result = super.parseHide(token);
+    indent--;
+    return result;
+  }
+
+  Token parseShow(Token token) {
+    doPrint('parseShow(' '$token)');
+    indent++;
+    var result = super.parseShow(token);
+    indent--;
+    return result;
+  }
+
+  Token parseIdentifierList(Token token) {
+    doPrint('parseIdentifierList(' '$token)');
+    indent++;
+    var result = super.parseIdentifierList(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTypeList(Token token) {
+    doPrint('parseTypeList(' '$token)');
+    indent++;
+    var result = super.parseTypeList(token);
+    indent--;
+    return result;
+  }
+
+  Token parsePartOrPartOf(Token partKeyword, DirectiveContext directiveState) {
+    doPrint('parsePartOrPartOf(' '$partKeyword, ' '$directiveState)');
+    indent++;
+    var result = super.parsePartOrPartOf(partKeyword, directiveState);
+    indent--;
+    return result;
+  }
+
+  Token parsePart(Token partKeyword) {
+    doPrint('parsePart(' '$partKeyword)');
+    indent++;
+    var result = super.parsePart(partKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parsePartOf(Token partKeyword) {
+    doPrint('parsePartOf(' '$partKeyword)');
+    indent++;
+    var result = super.parsePartOf(partKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseMetadataStar(Token token) {
+    doPrint('parseMetadataStar(' '$token)');
+    indent++;
+    var result = super.parseMetadataStar(token);
+    indent--;
+    return result;
+  }
+
+  Token parseMetadata(Token token) {
+    doPrint('parseMetadata(' '$token)');
+    indent++;
+    var result = super.parseMetadata(token);
+    indent--;
+    return result;
+  }
+
+  Token parseScript(Token token) {
+    doPrint('parseScript(' '$token)');
+    indent++;
+    var result = super.parseScript(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTypedef(Token typedefKeyword) {
+    doPrint('parseTypedef(' '$typedefKeyword)');
+    indent++;
+    var result = super.parseTypedef(typedefKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseMixinApplicationRest(Token token) {
+    doPrint('parseMixinApplicationRest(' '$token)');
+    indent++;
+    var result = super.parseMixinApplicationRest(token);
+    indent--;
+    return result;
+  }
+
+  Token parseWithClauseOpt(Token token) {
+    doPrint('parseWithClauseOpt(' '$token)');
+    indent++;
+    var result = super.parseWithClauseOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseGetterOrFormalParameters(
+      Token token, Token name, bool isGetter, MemberKind kind) {
+    doPrint('parseGetterOrFormalParameters('
+        '$token, '
+        '$name, '
+        '$isGetter, '
+        '$kind)');
+    indent++;
+    var result =
+        super.parseGetterOrFormalParameters(token, name, isGetter, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseFormalParametersOpt(Token token, MemberKind kind) {
+    doPrint('parseFormalParametersOpt(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseFormalParametersOpt(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token skipFormalParameters(Token token, MemberKind kind) {
+    doPrint('skipFormalParameters(' '$token, ' '$kind)');
+    indent++;
+    var result = super.skipFormalParameters(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token skipFormalParametersRest(Token token, MemberKind kind) {
+    doPrint('skipFormalParametersRest(' '$token, ' '$kind)');
+    indent++;
+    var result = super.skipFormalParametersRest(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseFormalParametersRequiredOpt(Token token, MemberKind kind) {
+    doPrint('parseFormalParametersRequiredOpt(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseFormalParametersRequiredOpt(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseFormalParameters(Token token, MemberKind kind) {
+    doPrint('parseFormalParameters(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseFormalParameters(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseFormalParametersRest(Token token, MemberKind kind) {
+    doPrint('parseFormalParametersRest(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseFormalParametersRest(token, kind);
+    indent--;
+    return result;
+  }
+
+  Message missingParameterMessage(MemberKind kind) {
+    doPrint('missingParameterMessage(' '$kind)');
+    indent++;
+    var result = super.missingParameterMessage(kind);
+    indent--;
+    return result;
+  }
+
+  Token parseFormalParameter(
+      Token token, FormalParameterKind parameterKind, MemberKind memberKind) {
+    doPrint(
+        'parseFormalParameter(' '$token, ' '$parameterKind, ' '$memberKind)');
+    indent++;
+    var result = super.parseFormalParameter(token, parameterKind, memberKind);
+    indent--;
+    return result;
+  }
+
+  Token parseOptionalPositionalParameters(Token token, MemberKind kind) {
+    doPrint('parseOptionalPositionalParameters(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseOptionalPositionalParameters(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseOptionalNamedParameters(Token token, MemberKind kind) {
+    doPrint('parseOptionalNamedParameters(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseOptionalNamedParameters(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseQualified(Token token, IdentifierContext context,
+      IdentifierContext continuationContext) {
+    doPrint('parseQualified(' '$token, ' '$context, ' '$continuationContext)');
+    indent++;
+    var result = super.parseQualified(token, context, continuationContext);
+    indent--;
+    return result;
+  }
+
+  Token parseQualifiedRestOpt(
+      Token token, IdentifierContext continuationContext) {
+    doPrint('parseQualifiedRestOpt(' '$token, ' '$continuationContext)');
+    indent++;
+    var result = super.parseQualifiedRestOpt(token, continuationContext);
+    indent--;
+    return result;
+  }
+
+  Token parseQualifiedRest(Token token, IdentifierContext context) {
+    doPrint('parseQualifiedRest(' '$token, ' '$context)');
+    indent++;
+    var result = super.parseQualifiedRest(token, context);
+    indent--;
+    return result;
+  }
+
+  Token skipBlock(Token token) {
+    doPrint('skipBlock(' '$token)');
+    indent++;
+    var result = super.skipBlock(token);
+    indent--;
+    return result;
+  }
+
+  Token parseEnum(Token enumKeyword) {
+    doPrint('parseEnum(' '$enumKeyword)');
+    indent++;
+    var result = super.parseEnum(enumKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseClassOrNamedMixinApplication(
+      Token abstractToken, Token classKeyword) {
+    doPrint('parseClassOrNamedMixinApplication('
+        '$abstractToken, '
+        '$classKeyword)');
+    indent++;
+    var result =
+        super.parseClassOrNamedMixinApplication(abstractToken, classKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseNamedMixinApplication(
+      Token token, Token begin, Token classKeyword) {
+    doPrint(
+        'parseNamedMixinApplication(' '$token, ' '$begin, ' '$classKeyword)');
+    indent++;
+    var result = super.parseNamedMixinApplication(token, begin, classKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseClass(
+      Token token, Token begin, Token classKeyword, String className) {
+    doPrint(
+        'parseClass(' '$token, ' '$begin, ' '$classKeyword, ' '$className)');
+    indent++;
+    var result = super.parseClass(token, begin, classKeyword, className);
+    indent--;
+    return result;
+  }
+
+  Token parseClassHeaderOpt(Token token, Token begin, Token classKeyword) {
+    doPrint('parseClassHeaderOpt(' '$token, ' '$begin, ' '$classKeyword)');
+    indent++;
+    var result = super.parseClassHeaderOpt(token, begin, classKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseClassHeaderRecovery(Token token, Token begin, Token classKeyword) {
+    doPrint('parseClassHeaderRecovery(' '$token, ' '$begin, ' '$classKeyword)');
+    indent++;
+    var result = super.parseClassHeaderRecovery(token, begin, classKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseClassExtendsOpt(Token token) {
+    doPrint('parseClassExtendsOpt(' '$token)');
+    indent++;
+    var result = super.parseClassExtendsOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseClassOrMixinImplementsOpt(Token token) {
+    doPrint('parseClassOrMixinImplementsOpt(' '$token)');
+    indent++;
+    var result = super.parseClassOrMixinImplementsOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseMixin(Token mixinKeyword) {
+    doPrint('parseMixin(' '$mixinKeyword)');
+    indent++;
+    var result = super.parseMixin(mixinKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseMixinHeaderOpt(Token token, Token mixinKeyword) {
+    doPrint('parseMixinHeaderOpt(' '$token, ' '$mixinKeyword)');
+    indent++;
+    var result = super.parseMixinHeaderOpt(token, mixinKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseMixinHeaderRecovery(
+      Token token, Token mixinKeyword, Token headerStart) {
+    doPrint('parseMixinHeaderRecovery('
+        '$token, '
+        '$mixinKeyword, '
+        '$headerStart)');
+    indent++;
+    var result =
+        super.parseMixinHeaderRecovery(token, mixinKeyword, headerStart);
+    indent--;
+    return result;
+  }
+
+  Token parseMixinOnOpt(Token token) {
+    doPrint('parseMixinOnOpt(' '$token)');
+    indent++;
+    var result = super.parseMixinOnOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseMixinOn(Token token) {
+    doPrint('parseMixinOn(' '$token)');
+    indent++;
+    var result = super.parseMixinOn(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExtension(Token extensionKeyword) {
+    doPrint('parseExtension(' '$extensionKeyword)');
+    indent++;
+    var result = super.parseExtension(extensionKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseStringPart(Token token) {
+    doPrint('parseStringPart(' '$token)');
+    indent++;
+    var result = super.parseStringPart(token);
+    indent--;
+    return result;
+  }
+
+  Token insertSyntheticIdentifier(Token token, IdentifierContext context,
+      {Message message, Token messageOnToken}) {
+    doPrint('insertSyntheticIdentifier('
+        '$token, '
+        '$context, '
+        'message: $message, '
+        'messageOnToken: $messageOnToken)');
+    indent++;
+    var result = super.insertSyntheticIdentifier(token, context,
+        message: message, messageOnToken: messageOnToken);
+    indent--;
+    return result;
+  }
+
+  Token ensureIdentifier(Token token, IdentifierContext context) {
+    doPrint('ensureIdentifier(' '$token, ' '$context)');
+    indent++;
+    var result = super.ensureIdentifier(token, context);
+    indent--;
+    return result;
+  }
+
+  bool notEofOrValue(String value, Token token) {
+    doPrint('notEofOrValue(' '$value, ' '$token)');
+    indent++;
+    var result = super.notEofOrValue(value, token);
+    indent--;
+    return result;
+  }
+
+  Token parseTypeVariablesOpt(Token token) {
+    doPrint('parseTypeVariablesOpt(' '$token)');
+    indent++;
+    var result = super.parseTypeVariablesOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTopLevelMember(Token token) {
+    doPrint('parseTopLevelMember(' '$token)');
+    indent++;
+    var result = super.parseTopLevelMember(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTopLevelMemberImpl(Token token) {
+    doPrint('parseTopLevelMemberImpl(' '$token)');
+    indent++;
+    var result = super.parseTopLevelMemberImpl(token);
+    indent--;
+    return result;
+  }
+
+  Token parseFields(
+      Token beforeStart,
+      Token externalToken,
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      Token beforeType,
+      TypeInfo typeInfo,
+      Token name,
+      DeclarationKind kind) {
+    doPrint('parseFields('
+        '$beforeStart, '
+        '$externalToken, '
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$beforeType, '
+        '$typeInfo, '
+        '$name, '
+        '$kind)');
+    indent++;
+    var result = super.parseFields(
+        beforeStart,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        beforeType,
+        typeInfo,
+        name,
+        kind);
+    indent--;
+    return result;
+  }
+
+  Token parseTopLevelMethod(Token beforeStart, Token externalToken,
+      Token beforeType, TypeInfo typeInfo, Token getOrSet, Token name) {
+    doPrint('parseTopLevelMethod('
+        '$beforeStart, '
+        '$externalToken, '
+        '$beforeType, '
+        '$typeInfo, '
+        '$getOrSet, '
+        '$name)');
+    indent++;
+    var result = super.parseTopLevelMethod(
+        beforeStart, externalToken, beforeType, typeInfo, getOrSet, name);
+    indent--;
+    return result;
+  }
+
+  Token parseMethodTypeVar(Token name) {
+    doPrint('parseMethodTypeVar(' '$name)');
+    indent++;
+    var result = super.parseMethodTypeVar(name);
+    indent--;
+    return result;
+  }
+
+  Token parseFieldInitializerOpt(Token token, Token name, Token lateToken,
+      Token varFinalOrConst, DeclarationKind kind) {
+    doPrint('parseFieldInitializerOpt('
+        '$token, '
+        '$name, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$kind)');
+    indent++;
+    var result = super.parseFieldInitializerOpt(
+        token, name, lateToken, varFinalOrConst, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseVariableInitializerOpt(Token token) {
+    doPrint('parseVariableInitializerOpt(' '$token)');
+    indent++;
+    var result = super.parseVariableInitializerOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseInitializersOpt(Token token) {
+    doPrint('parseInitializersOpt(' '$token)');
+    indent++;
+    var result = super.parseInitializersOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseInitializers(Token token) {
+    doPrint('parseInitializers(' '$token)');
+    indent++;
+    var result = super.parseInitializers(token);
+    indent--;
+    return result;
+  }
+
+  Token parseInitializer(Token token) {
+    doPrint('parseInitializer(' '$token)');
+    indent++;
+    var result = super.parseInitializer(token);
+    indent--;
+    return result;
+  }
+
+  Token parseSuperInitializerExpression(final Token start) {
+    doPrint('parseSuperInitializerExpression(' '$start)');
+    indent++;
+    var result = super.parseSuperInitializerExpression(start);
+    indent--;
+    return result;
+  }
+
+  Token parseInitializerExpressionRest(Token token) {
+    doPrint('parseInitializerExpressionRest(' '$token)');
+    indent++;
+    var result = super.parseInitializerExpressionRest(token);
+    indent--;
+    return result;
+  }
+
+  Token ensureBlock(Token token,
+      Template<Message Function(Token token)> template, String blockKind) {
+    doPrint('ensureBlock(' '$token, ' '$template, ' '$blockKind)');
+    indent++;
+    var result = super.ensureBlock(token, template, blockKind);
+    indent--;
+    return result;
+  }
+
+  Token insertBlock(Token token) {
+    doPrint('insertBlock(' '$token)');
+    indent++;
+    var result = super.insertBlock(token);
+    indent--;
+    return result;
+  }
+
+  Token ensureCloseParen(Token token, Token openParen) {
+    doPrint('ensureCloseParen(' '$token, ' '$openParen)');
+    indent++;
+    var result = super.ensureCloseParen(token, openParen);
+    indent--;
+    return result;
+  }
+
+  Token ensureColon(Token token) {
+    doPrint('ensureColon(' '$token)');
+    indent++;
+    var result = super.ensureColon(token);
+    indent--;
+    return result;
+  }
+
+  Token ensureLiteralString(Token token) {
+    doPrint('ensureLiteralString(' '$token)');
+    indent++;
+    var result = super.ensureLiteralString(token);
+    indent--;
+    return result;
+  }
+
+  Token ensureSemicolon(Token token) {
+    doPrint('ensureSemicolon(' '$token)');
+    indent++;
+    var result = super.ensureSemicolon(token);
+    indent--;
+    return result;
+  }
+
+  Token rewriteAndRecover(Token token, Message message, Token newToken) {
+    doPrint('rewriteAndRecover(' '$token, ' '$message, ' '$newToken)');
+    indent++;
+    var result = super.rewriteAndRecover(token, message, newToken);
+    indent--;
+    return result;
+  }
+
+  Token rewriteSquareBrackets(Token token) {
+    doPrint('rewriteSquareBrackets(' '$token)');
+    indent++;
+    var result = super.rewriteSquareBrackets(token);
+    indent--;
+    return result;
+  }
+
+  Token skipUnexpectedTokenOpt(Token token, List<String> expectedNext) {
+    doPrint('skipUnexpectedTokenOpt(' '$token, ' '$expectedNext)');
+    indent++;
+    var result = super.skipUnexpectedTokenOpt(token, expectedNext);
+    indent--;
+    return result;
+  }
+
+  Token parseNativeClause(Token token) {
+    doPrint('parseNativeClause(' '$token)');
+    indent++;
+    var result = super.parseNativeClause(token);
+    indent--;
+    return result;
+  }
+
+  Token skipClassOrMixinOrExtensionBody(Token token) {
+    doPrint('skipClassOrMixinOrExtensionBody(' '$token)');
+    indent++;
+    var result = super.skipClassOrMixinOrExtensionBody(token);
+    indent--;
+    return result;
+  }
+
+  Token parseClassOrMixinOrExtensionBody(
+      Token token, DeclarationKind kind, String enclosingDeclarationName) {
+    doPrint('parseClassOrMixinOrExtensionBody('
+        '$token, '
+        '$kind, '
+        '$enclosingDeclarationName)');
+    indent++;
+    var result = super.parseClassOrMixinOrExtensionBody(
+        token, kind, enclosingDeclarationName);
+    indent--;
+    return result;
+  }
+
+  bool isUnaryMinus(Token token) {
+    doPrint('isUnaryMinus(' '$token)');
+    indent++;
+    var result = super.isUnaryMinus(token);
+    indent--;
+    return result;
+  }
+
+  Token parseClassMember(Token token, String className) {
+    doPrint('parseClassMember(' '$token, ' '$className)');
+    indent++;
+    var result = super.parseClassMember(token, className);
+    indent--;
+    return result;
+  }
+
+  Token parseMixinMember(Token token, String mixinName) {
+    doPrint('parseMixinMember(' '$token, ' '$mixinName)');
+    indent++;
+    var result = super.parseMixinMember(token, mixinName);
+    indent--;
+    return result;
+  }
+
+  Token parseExtensionMember(Token token, String extensionName) {
+    doPrint('parseExtensionMember(' '$token, ' '$extensionName)');
+    indent++;
+    var result = super.parseExtensionMember(token, extensionName);
+    indent--;
+    return result;
+  }
+
+  Token parseClassOrMixinOrExtensionMemberImpl(
+      Token token, DeclarationKind kind, String enclosingDeclarationName) {
+    doPrint('parseClassOrMixinOrExtensionMemberImpl('
+        '$token, '
+        '$kind, '
+        '$enclosingDeclarationName)');
+    indent++;
+    var result = super.parseClassOrMixinOrExtensionMemberImpl(
+        token, kind, enclosingDeclarationName);
+    indent--;
+    return result;
+  }
+
+  Token parseMethod(
+      Token beforeStart,
+      Token externalToken,
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      Token beforeType,
+      TypeInfo typeInfo,
+      Token getOrSet,
+      Token name,
+      DeclarationKind kind,
+      String enclosingDeclarationName) {
+    doPrint('parseMethod('
+        '$beforeStart, '
+        '$externalToken, '
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$beforeType, '
+        '$typeInfo, '
+        '$getOrSet, '
+        '$name, '
+        '$kind, '
+        '$enclosingDeclarationName)');
+    indent++;
+    var result = super.parseMethod(
+        beforeStart,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        beforeType,
+        typeInfo,
+        getOrSet,
+        name,
+        kind,
+        enclosingDeclarationName);
+    indent--;
+    return result;
+  }
+
+  Token parseFactoryMethod(Token token, DeclarationKind kind, Token beforeStart,
+      Token externalToken, Token staticOrCovariant, Token varFinalOrConst) {
+    doPrint('parseFactoryMethod('
+        '$token, '
+        '$kind, '
+        '$beforeStart, '
+        '$externalToken, '
+        '$staticOrCovariant, '
+        '$varFinalOrConst)');
+    indent++;
+    var result = super.parseFactoryMethod(token, kind, beforeStart,
+        externalToken, staticOrCovariant, varFinalOrConst);
+    indent--;
+    return result;
+  }
+
+  Token parseOperatorName(Token token) {
+    doPrint('parseOperatorName(' '$token)');
+    indent++;
+    var result = super.parseOperatorName(token);
+    indent--;
+    return result;
+  }
+
+  Token parseFunctionExpression(Token token) {
+    doPrint('parseFunctionExpression(' '$token)');
+    indent++;
+    var result = super.parseFunctionExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseFunctionLiteral(
+      Token start,
+      Token beforeName,
+      Token name,
+      TypeInfo typeInfo,
+      TypeParamOrArgInfo typeParam,
+      IdentifierContext context) {
+    doPrint('parseFunctionLiteral('
+        '$start, '
+        '$beforeName, '
+        '$name, '
+        '$typeInfo, '
+        '$typeParam, '
+        '$context)');
+    indent++;
+    var result = super.parseFunctionLiteral(
+        start, beforeName, name, typeInfo, typeParam, context);
+    indent--;
+    return result;
+  }
+
+  Token parseNamedFunctionRest(
+      Token beforeName, Token begin, Token formals, bool isFunctionExpression) {
+    doPrint('parseNamedFunctionRest('
+        '$beforeName, '
+        '$begin, '
+        '$formals, '
+        '$isFunctionExpression)');
+    indent++;
+    var result = super.parseNamedFunctionRest(
+        beforeName, begin, formals, isFunctionExpression);
+    indent--;
+    return result;
+  }
+
+  Token parseAsyncOptBody(
+      Token token, bool ofFunctionExpression, bool allowAbstract) {
+    doPrint('parseAsyncOptBody('
+        '$token, '
+        '$ofFunctionExpression, '
+        '$allowAbstract)');
+    indent++;
+    var result =
+        super.parseAsyncOptBody(token, ofFunctionExpression, allowAbstract);
+    indent--;
+    return result;
+  }
+
+  Token parseConstructorReference(Token token, [TypeParamOrArgInfo typeArg]) {
+    doPrint('parseConstructorReference(' '$token, ' '$typeArg)');
+    indent++;
+    var result = super.parseConstructorReference(token, typeArg);
+    indent--;
+    return result;
+  }
+
+  Token parseRedirectingFactoryBody(Token token) {
+    doPrint('parseRedirectingFactoryBody(' '$token)');
+    indent++;
+    var result = super.parseRedirectingFactoryBody(token);
+    indent--;
+    return result;
+  }
+
+  Token skipFunctionBody(Token token, bool isExpression, bool allowAbstract) {
+    doPrint('skipFunctionBody(' '$token, ' '$isExpression, ' '$allowAbstract)');
+    indent++;
+    var result = super.skipFunctionBody(token, isExpression, allowAbstract);
+    indent--;
+    return result;
+  }
+
+  Token parseFunctionBody(
+      Token token, bool ofFunctionExpression, bool allowAbstract) {
+    doPrint('parseFunctionBody('
+        '$token, '
+        '$ofFunctionExpression, '
+        '$allowAbstract)');
+    indent++;
+    var result =
+        super.parseFunctionBody(token, ofFunctionExpression, allowAbstract);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionFunctionBody(Token token, bool ofFunctionExpression) {
+    doPrint('parseExpressionFunctionBody(' '$token, ' '$ofFunctionExpression)');
+    indent++;
+    var result = super.parseExpressionFunctionBody(token, ofFunctionExpression);
+    indent--;
+    return result;
+  }
+
+  Token skipAsyncModifier(Token token) {
+    doPrint('skipAsyncModifier(' '$token)');
+    indent++;
+    var result = super.skipAsyncModifier(token);
+    indent--;
+    return result;
+  }
+
+  Token parseAsyncModifierOpt(Token token) {
+    doPrint('parseAsyncModifierOpt(' '$token)');
+    indent++;
+    var result = super.parseAsyncModifierOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseStatement(Token token) {
+    doPrint('parseStatement(' '$token)');
+    indent++;
+    var result = super.parseStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseStatementX(Token token) {
+    doPrint('parseStatementX(' '$token)');
+    indent++;
+    var result = super.parseStatementX(token);
+    indent--;
+    return result;
+  }
+
+  Token parseYieldStatement(Token token) {
+    doPrint('parseYieldStatement(' '$token)');
+    indent++;
+    var result = super.parseYieldStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseReturnStatement(Token token) {
+    doPrint('parseReturnStatement(' '$token)');
+    indent++;
+    var result = super.parseReturnStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLabel(Token token) {
+    doPrint('parseLabel(' '$token)');
+    indent++;
+    var result = super.parseLabel(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLabeledStatement(Token token) {
+    doPrint('parseLabeledStatement(' '$token)');
+    indent++;
+    var result = super.parseLabeledStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionStatement(Token token) {
+    doPrint('parseExpressionStatement(' '$token)');
+    indent++;
+    var result = super.parseExpressionStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExpression(Token token) {
+    doPrint('parseExpression(' '$token)');
+    indent++;
+    var result = super.parseExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionWithoutCascade(Token token) {
+    doPrint('parseExpressionWithoutCascade(' '$token)');
+    indent++;
+    var result = super.parseExpressionWithoutCascade(token);
+    indent--;
+    return result;
+  }
+
+  Token parseConditionalExpressionRest(Token token) {
+    doPrint('parseConditionalExpressionRest(' '$token)');
+    indent++;
+    var result = super.parseConditionalExpressionRest(token);
+    indent--;
+    return result;
+  }
+
+  Token parsePrecedenceExpression(
+      Token token, int precedence, bool allowCascades) {
+    doPrint('parsePrecedenceExpression('
+        '$token, '
+        '$precedence, '
+        '$allowCascades)');
+    indent++;
+    var result =
+        super.parsePrecedenceExpression(token, precedence, allowCascades);
+    indent--;
+    return result;
+  }
+
+  Token parseCascadeExpression(Token token) {
+    doPrint('parseCascadeExpression(' '$token)');
+    indent++;
+    var result = super.parseCascadeExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseUnaryExpression(Token token, bool allowCascades) {
+    doPrint('parseUnaryExpression(' '$token, ' '$allowCascades)');
+    indent++;
+    var result = super.parseUnaryExpression(token, allowCascades);
+    indent--;
+    return result;
+  }
+
+  Token parseArgumentOrIndexStar(Token token, TypeParamOrArgInfo typeArg) {
+    doPrint('parseArgumentOrIndexStar(' '$token, ' '$typeArg)');
+    indent++;
+    var result = super.parseArgumentOrIndexStar(token, typeArg);
+    indent--;
+    return result;
+  }
+
+  Token parsePrimary(Token token, IdentifierContext context) {
+    doPrint('parsePrimary(' '$token, ' '$context)');
+    indent++;
+    var result = super.parsePrimary(token, context);
+    indent--;
+    return result;
+  }
+
+  Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
+    doPrint('parseParenthesizedExpressionOrFunctionLiteral(' '$token)');
+    indent++;
+    var result = super.parseParenthesizedExpressionOrFunctionLiteral(token);
+    indent--;
+    return result;
+  }
+
+  Token ensureParenthesizedCondition(Token token) {
+    doPrint('ensureParenthesizedCondition(' '$token)');
+    indent++;
+    var result = super.ensureParenthesizedCondition(token);
+    indent--;
+    return result;
+  }
+
+  Token parseParenthesizedExpression(Token token) {
+    doPrint('parseParenthesizedExpression(' '$token)');
+    indent++;
+    var result = super.parseParenthesizedExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionInParenthesis(Token token) {
+    doPrint('parseExpressionInParenthesis(' '$token)');
+    indent++;
+    var result = super.parseExpressionInParenthesis(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionInParenthesisRest(Token token) {
+    doPrint('parseExpressionInParenthesisRest(' '$token)');
+    indent++;
+    var result = super.parseExpressionInParenthesisRest(token);
+    indent--;
+    return result;
+  }
+
+  Token parseThisExpression(Token token, IdentifierContext context) {
+    doPrint('parseThisExpression(' '$token, ' '$context)');
+    indent++;
+    var result = super.parseThisExpression(token, context);
+    indent--;
+    return result;
+  }
+
+  Token parseSuperExpression(Token token, IdentifierContext context) {
+    doPrint('parseSuperExpression(' '$token, ' '$context)');
+    indent++;
+    var result = super.parseSuperExpression(token, context);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralListSuffix(Token token, Token constKeyword) {
+    doPrint('parseLiteralListSuffix(' '$token, ' '$constKeyword)');
+    indent++;
+    var result = super.parseLiteralListSuffix(token, constKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralSetOrMapSuffix(Token token, Token constKeyword) {
+    doPrint('parseLiteralSetOrMapSuffix(' '$token, ' '$constKeyword)');
+    indent++;
+    var result = super.parseLiteralSetOrMapSuffix(token, constKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralFunctionSuffix(Token token) {
+    doPrint('parseLiteralFunctionSuffix(' '$token)');
+    indent++;
+    var result = super.parseLiteralFunctionSuffix(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralListSetMapOrFunction(
+      final Token start, Token constKeyword) {
+    doPrint('parseLiteralListSetMapOrFunction(' '$start, ' '$constKeyword)');
+    indent++;
+    var result = super.parseLiteralListSetMapOrFunction(start, constKeyword);
+    indent--;
+    return result;
+  }
+
+  Token parseMapLiteralEntry(Token token) {
+    doPrint('parseMapLiteralEntry(' '$token)');
+    indent++;
+    var result = super.parseMapLiteralEntry(token);
+    indent--;
+    return result;
+  }
+
+  Token parseSendOrFunctionLiteral(Token token, IdentifierContext context) {
+    doPrint('parseSendOrFunctionLiteral(' '$token, ' '$context)');
+    indent++;
+    var result = super.parseSendOrFunctionLiteral(token, context);
+    indent--;
+    return result;
+  }
+
+  Token ensureArguments(Token token) {
+    doPrint('ensureArguments(' '$token)');
+    indent++;
+    var result = super.ensureArguments(token);
+    indent--;
+    return result;
+  }
+
+  Token parseConstructorInvocationArguments(Token token) {
+    doPrint('parseConstructorInvocationArguments(' '$token)');
+    indent++;
+    var result = super.parseConstructorInvocationArguments(token);
+    indent--;
+    return result;
+  }
+
+  Token parseNewExpression(Token token) {
+    doPrint('parseNewExpression(' '$token)');
+    indent++;
+    var result = super.parseNewExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseImplicitCreationExpression(
+      Token token, TypeParamOrArgInfo typeArg) {
+    doPrint('parseImplicitCreationExpression(' '$token, ' '$typeArg)');
+    indent++;
+    var result = super.parseImplicitCreationExpression(token, typeArg);
+    indent--;
+    return result;
+  }
+
+  Token parseConstExpression(Token token) {
+    doPrint('parseConstExpression(' '$token)');
+    indent++;
+    var result = super.parseConstExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralInt(Token token) {
+    doPrint('parseLiteralInt(' '$token)');
+    indent++;
+    var result = super.parseLiteralInt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralDouble(Token token) {
+    doPrint('parseLiteralDouble(' '$token)');
+    indent++;
+    var result = super.parseLiteralDouble(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralString(Token token) {
+    doPrint('parseLiteralString(' '$token)');
+    indent++;
+    var result = super.parseLiteralString(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralSymbol(Token token) {
+    doPrint('parseLiteralSymbol(' '$token)');
+    indent++;
+    var result = super.parseLiteralSymbol(token);
+    indent--;
+    return result;
+  }
+
+  Token parseSingleLiteralString(Token token) {
+    doPrint('parseSingleLiteralString(' '$token)');
+    indent++;
+    var result = super.parseSingleLiteralString(token);
+    indent--;
+    return result;
+  }
+
+  Token parseIdentifierExpression(Token token) {
+    doPrint('parseIdentifierExpression(' '$token)');
+    indent++;
+    var result = super.parseIdentifierExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralBool(Token token) {
+    doPrint('parseLiteralBool(' '$token)');
+    indent++;
+    var result = super.parseLiteralBool(token);
+    indent--;
+    return result;
+  }
+
+  Token parseLiteralNull(Token token) {
+    doPrint('parseLiteralNull(' '$token)');
+    indent++;
+    var result = super.parseLiteralNull(token);
+    indent--;
+    return result;
+  }
+
+  Token parseSend(Token token, IdentifierContext context) {
+    doPrint('parseSend(' '$token, ' '$context)');
+    indent++;
+    var result = super.parseSend(token, context);
+    indent--;
+    return result;
+  }
+
+  Token skipArgumentsOpt(Token token) {
+    doPrint('skipArgumentsOpt(' '$token)');
+    indent++;
+    var result = super.skipArgumentsOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseArgumentsOpt(Token token) {
+    doPrint('parseArgumentsOpt(' '$token)');
+    indent++;
+    var result = super.parseArgumentsOpt(token);
+    indent--;
+    return result;
+  }
+
+  Token parseArguments(Token token) {
+    doPrint('parseArguments(' '$token)');
+    indent++;
+    var result = super.parseArguments(token);
+    indent--;
+    return result;
+  }
+
+  Token parseArgumentsRest(Token token) {
+    doPrint('parseArgumentsRest(' '$token)');
+    indent++;
+    var result = super.parseArgumentsRest(token);
+    indent--;
+    return result;
+  }
+
+  Token parseIsOperatorRest(Token token) {
+    doPrint('parseIsOperatorRest(' '$token)');
+    indent++;
+    var result = super.parseIsOperatorRest(token);
+    indent--;
+    return result;
+  }
+
+  TypeInfo computeTypeAfterIsOrAs(Token token) {
+    doPrint('computeTypeAfterIsOrAs(' '$token)');
+    indent++;
+    var result = super.computeTypeAfterIsOrAs(token);
+    indent--;
+    return result;
+  }
+
+  Token parseAsOperatorRest(Token token) {
+    doPrint('parseAsOperatorRest(' '$token)');
+    indent++;
+    var result = super.parseAsOperatorRest(token);
+    indent--;
+    return result;
+  }
+
+  Token skipChainedAsIsOperators(Token token) {
+    doPrint('skipChainedAsIsOperators(' '$token)');
+    indent++;
+    var result = super.skipChainedAsIsOperators(token);
+    indent--;
+    return result;
+  }
+
+  bool looksLikeLocalFunction(Token token) {
+    doPrint('looksLikeLocalFunction(' '$token)');
+    indent++;
+    var result = super.looksLikeLocalFunction(token);
+    indent--;
+    return result;
+  }
+
+  bool looksLikeFunctionBody(Token token) {
+    doPrint('looksLikeFunctionBody(' '$token)');
+    indent++;
+    var result = super.looksLikeFunctionBody(token);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionStatementOrConstDeclaration(final Token start) {
+    doPrint('parseExpressionStatementOrConstDeclaration(' '$start)');
+    indent++;
+    var result = super.parseExpressionStatementOrConstDeclaration(start);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionStatementOrDeclaration(final Token start,
+      [bool onlyParseVariableDeclarationStart = false]) {
+    doPrint('parseExpressionStatementOrDeclaration('
+        '$start, '
+        '$onlyParseVariableDeclarationStart)');
+    indent++;
+    var result = super.parseExpressionStatementOrDeclaration(
+        start, onlyParseVariableDeclarationStart);
+    indent--;
+    return result;
+  }
+
+  Token parseExpressionStatementOrDeclarationAfterModifiers(
+      final Token beforeType,
+      final Token start,
+      final Token lateToken,
+      Token varFinalOrConst,
+      TypeInfo typeInfo,
+      bool onlyParseVariableDeclarationStart) {
+    doPrint('parseExpressionStatementOrDeclarationAfterModifiers('
+        '$beforeType, '
+        '$start, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$typeInfo, '
+        '$onlyParseVariableDeclarationStart)');
+    indent++;
+    var result = super.parseExpressionStatementOrDeclarationAfterModifiers(
+        beforeType,
+        start,
+        lateToken,
+        varFinalOrConst,
+        typeInfo,
+        onlyParseVariableDeclarationStart);
+    indent--;
+    return result;
+  }
+
+  Token parseVariablesDeclarationRest(Token token, bool endWithSemicolon) {
+    doPrint('parseVariablesDeclarationRest(' '$token, ' '$endWithSemicolon)');
+    indent++;
+    var result = super.parseVariablesDeclarationRest(token, endWithSemicolon);
+    indent--;
+    return result;
+  }
+
+  Token parseOptionallyInitializedIdentifier(Token token) {
+    doPrint('parseOptionallyInitializedIdentifier(' '$token)');
+    indent++;
+    var result = super.parseOptionallyInitializedIdentifier(token);
+    indent--;
+    return result;
+  }
+
+  Token parseIfStatement(Token token) {
+    doPrint('parseIfStatement(' '$token)');
+    indent++;
+    var result = super.parseIfStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseForStatement(Token token, Token awaitToken) {
+    doPrint('parseForStatement(' '$token, ' '$awaitToken)');
+    indent++;
+    var result = super.parseForStatement(token, awaitToken);
+    indent--;
+    return result;
+  }
+
+  Token parseForLoopPartsStart(Token awaitToken, Token forToken) {
+    doPrint('parseForLoopPartsStart(' '$awaitToken, ' '$forToken)');
+    indent++;
+    var result = super.parseForLoopPartsStart(awaitToken, forToken);
+    indent--;
+    return result;
+  }
+
+  Token parseForLoopPartsMid(Token token, Token awaitToken, Token forToken) {
+    doPrint('parseForLoopPartsMid(' '$token, ' '$awaitToken, ' '$forToken)');
+    indent++;
+    var result = super.parseForLoopPartsMid(token, awaitToken, forToken);
+    indent--;
+    return result;
+  }
+
+  Token parseForRest(Token awaitToken, Token token, Token forToken) {
+    doPrint('parseForRest(' '$awaitToken, ' '$token, ' '$forToken)');
+    indent++;
+    var result = super.parseForRest(awaitToken, token, forToken);
+    indent--;
+    return result;
+  }
+
+  Token parseForLoopPartsRest(Token token, Token forToken, Token awaitToken) {
+    doPrint('parseForLoopPartsRest(' '$token, ' '$forToken, ' '$awaitToken)');
+    indent++;
+    var result = super.parseForLoopPartsRest(token, forToken, awaitToken);
+    indent--;
+    return result;
+  }
+
+  Token parseForInRest(
+      Token token, Token awaitToken, Token forToken, Token identifier) {
+    doPrint('parseForInRest('
+        '$token, '
+        '$awaitToken, '
+        '$forToken, '
+        '$identifier)');
+    indent++;
+    var result = super.parseForInRest(token, awaitToken, forToken, identifier);
+    indent--;
+    return result;
+  }
+
+  Token parseForInLoopPartsRest(
+      Token token, Token awaitToken, Token forToken, Token identifier) {
+    doPrint('parseForInLoopPartsRest('
+        '$token, '
+        '$awaitToken, '
+        '$forToken, '
+        '$identifier)');
+    indent++;
+    var result =
+        super.parseForInLoopPartsRest(token, awaitToken, forToken, identifier);
+    indent--;
+    return result;
+  }
+
+  Token parseWhileStatement(Token token) {
+    doPrint('parseWhileStatement(' '$token)');
+    indent++;
+    var result = super.parseWhileStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseDoWhileStatement(Token token) {
+    doPrint('parseDoWhileStatement(' '$token)');
+    indent++;
+    var result = super.parseDoWhileStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseBlock(Token token, String blockKind) {
+    doPrint('parseBlock(' '$token, ' '$blockKind)');
+    indent++;
+    var result = super.parseBlock(token, blockKind);
+    indent--;
+    return result;
+  }
+
+  Token parseInvalidBlock(Token token) {
+    doPrint('parseInvalidBlock(' '$token)');
+    indent++;
+    var result = super.parseInvalidBlock(token);
+    indent--;
+    return result;
+  }
+
+  bool looksLikeAwaitExpression(Token token) {
+    doPrint('looksLikeAwaitExpression(' '$token)');
+    indent++;
+    var result = super.looksLikeAwaitExpression(token);
+    indent--;
+    return result;
+  }
+
+  Token parseAwaitExpression(Token token, bool allowCascades) {
+    doPrint('parseAwaitExpression(' '$token, ' '$allowCascades)');
+    indent++;
+    var result = super.parseAwaitExpression(token, allowCascades);
+    indent--;
+    return result;
+  }
+
+  Token parseThrowExpression(Token token, bool allowCascades) {
+    doPrint('parseThrowExpression(' '$token, ' '$allowCascades)');
+    indent++;
+    var result = super.parseThrowExpression(token, allowCascades);
+    indent--;
+    return result;
+  }
+
+  Token parseRethrowStatement(Token token) {
+    doPrint('parseRethrowStatement(' '$token)');
+    indent++;
+    var result = super.parseRethrowStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseTryStatement(Token token) {
+    doPrint('parseTryStatement(' '$token)');
+    indent++;
+    var result = super.parseTryStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseSwitchStatement(Token token) {
+    doPrint('parseSwitchStatement(' '$token)');
+    indent++;
+    var result = super.parseSwitchStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseSwitchBlock(Token token) {
+    doPrint('parseSwitchBlock(' '$token)');
+    indent++;
+    var result = super.parseSwitchBlock(token);
+    indent--;
+    return result;
+  }
+
+  Token peekPastLabels(Token token) {
+    doPrint('peekPastLabels(' '$token)');
+    indent++;
+    var result = super.peekPastLabels(token);
+    indent--;
+    return result;
+  }
+
+  Token parseStatementsInSwitchCase(
+      Token token,
+      Token peek,
+      Token begin,
+      int labelCount,
+      int expressionCount,
+      Token defaultKeyword,
+      Token colonAfterDefault) {
+    doPrint('parseStatementsInSwitchCase('
+        '$token, '
+        '$peek, '
+        '$begin, '
+        '$labelCount, '
+        '$expressionCount, '
+        '$defaultKeyword, '
+        '$colonAfterDefault)');
+    indent++;
+    var result = super.parseStatementsInSwitchCase(token, peek, begin,
+        labelCount, expressionCount, defaultKeyword, colonAfterDefault);
+    indent--;
+    return result;
+  }
+
+  Token parseBreakStatement(Token token) {
+    doPrint('parseBreakStatement(' '$token)');
+    indent++;
+    var result = super.parseBreakStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseAssert(Token token, Assert kind) {
+    doPrint('parseAssert(' '$token, ' '$kind)');
+    indent++;
+    var result = super.parseAssert(token, kind);
+    indent--;
+    return result;
+  }
+
+  Token parseAssertStatement(Token token) {
+    doPrint('parseAssertStatement(' '$token)');
+    indent++;
+    var result = super.parseAssertStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseContinueStatement(Token token) {
+    doPrint('parseContinueStatement(' '$token)');
+    indent++;
+    var result = super.parseContinueStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token parseEmptyStatement(Token token) {
+    doPrint('parseEmptyStatement(' '$token)');
+    indent++;
+    var result = super.parseEmptyStatement(token);
+    indent--;
+    return result;
+  }
+
+  Token previousToken(Token beforeToken, Token token) {
+    doPrint('previousToken(' '$beforeToken, ' '$token)');
+    indent++;
+    var result = super.previousToken(beforeToken, token);
+    indent--;
+    return result;
+  }
+
+  Token parseInvalidOperatorDeclaration(
+      Token beforeStart,
+      Token externalToken,
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      Token beforeType,
+      DeclarationKind kind) {
+    doPrint('parseInvalidOperatorDeclaration('
+        '$beforeStart, '
+        '$externalToken, '
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$beforeType, '
+        '$kind)');
+    indent++;
+    var result = super.parseInvalidOperatorDeclaration(
+        beforeStart,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        beforeType,
+        kind);
+    indent--;
+    return result;
+  }
+
+  Token recoverFromInvalidMember(
+      Token token,
+      Token beforeStart,
+      Token externalToken,
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      Token beforeType,
+      TypeInfo typeInfo,
+      Token getOrSet,
+      DeclarationKind kind,
+      String enclosingDeclarationName) {
+    doPrint('recoverFromInvalidMember('
+        '$token, '
+        '$beforeStart, '
+        '$externalToken, '
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$beforeType, '
+        '$typeInfo, '
+        '$getOrSet, '
+        '$kind, '
+        '$enclosingDeclarationName)');
+    indent++;
+    var result = super.recoverFromInvalidMember(
+        token,
+        beforeStart,
+        externalToken,
+        staticToken,
+        covariantToken,
+        lateToken,
+        varFinalOrConst,
+        beforeType,
+        typeInfo,
+        getOrSet,
+        kind,
+        enclosingDeclarationName);
+    indent--;
+    return result;
+  }
+
+  Token recoverFromStackOverflow(Token token) {
+    doPrint('recoverFromStackOverflow(' '$token)');
+    indent++;
+    var result = super.recoverFromStackOverflow(token);
+    indent--;
+    return result;
+  }
+
+  void reportRecoverableError(Token token, Message message) {
+    doPrint('reportRecoverableError(' '$token, ' '$message)');
+    indent++;
+    var result = super.reportRecoverableError(token, message);
+    indent--;
+    return result;
+  }
+
+  void reportRecoverableErrorWithToken(Token token, dynamic template) {
+    doPrint('reportRecoverableErrorWithToken(' '$token, ' '$template)');
+    indent++;
+    var result = super.reportRecoverableErrorWithToken(token, template);
+    indent--;
+    return result;
+  }
+
+  Token reportAllErrorTokens(Token token) {
+    doPrint('reportAllErrorTokens(' '$token)');
+    indent++;
+    var result = super.reportAllErrorTokens(token);
+    indent--;
+    return result;
+  }
+
+  Token skipErrorTokens(Token token) {
+    doPrint('skipErrorTokens(' '$token)');
+    indent++;
+    var result = super.skipErrorTokens(token);
+    indent--;
+    return result;
+  }
+
+  Token parseInvalidTopLevelDeclaration(Token token) {
+    doPrint('parseInvalidTopLevelDeclaration(' '$token)');
+    indent++;
+    var result = super.parseInvalidTopLevelDeclaration(token);
+    indent--;
+    return result;
+  }
+
+  Token reportAndSkipClassInClass(Token token) {
+    doPrint('reportAndSkipClassInClass(' '$token)');
+    indent++;
+    var result = super.reportAndSkipClassInClass(token);
+    indent--;
+    return result;
+  }
+
+  Token reportAndSkipEnumInClass(Token token) {
+    doPrint('reportAndSkipEnumInClass(' '$token)');
+    indent++;
+    var result = super.reportAndSkipEnumInClass(token);
+    indent--;
+    return result;
+  }
+
+  Token reportAndSkipTypedefInClass(Token token) {
+    doPrint('reportAndSkipTypedefInClass(' '$token)');
+    indent++;
+    var result = super.reportAndSkipTypedefInClass(token);
+    indent--;
+    return result;
+  }
+
+  Token link(BeginToken beginToken, Token endToken) {
+    doPrint('link(' '$beginToken, ' '$endToken)');
+    indent++;
+    var result = super.link(beginToken, endToken);
+    indent--;
+    return result;
+  }
+
+  Token syntheticPreviousToken(Token token) {
+    doPrint('syntheticPreviousToken(' '$token)');
+    indent++;
+    var result = super.syntheticPreviousToken(token);
+    indent--;
+    return result;
+  }
+
+  Token findDartDoc(Token token) {
+    doPrint('findDartDoc(' '$token)');
+    indent++;
+    var result = super.findDartDoc(token);
+    indent--;
+    return result;
+  }
+
+  int parseCommentReferences(Token dartdoc) {
+    doPrint('parseCommentReferences(' '$dartdoc)');
+    indent++;
+    var result = super.parseCommentReferences(dartdoc);
+    indent--;
+    return result;
+  }
+
+  int parseReferencesInMultiLineComment(Token multiLineDoc) {
+    doPrint('parseReferencesInMultiLineComment(' '$multiLineDoc)');
+    indent++;
+    var result = super.parseReferencesInMultiLineComment(multiLineDoc);
+    indent--;
+    return result;
+  }
+
+  int parseReferencesInSingleLineComments(Token token) {
+    doPrint('parseReferencesInSingleLineComments(' '$token)');
+    indent++;
+    var result = super.parseReferencesInSingleLineComments(token);
+    indent--;
+    return result;
+  }
+
+  int parseCommentReferencesInText(Token commentToken, int start, int end) {
+    doPrint(
+        'parseCommentReferencesInText(' '$commentToken, ' '$start, ' '$end)');
+    indent++;
+    var result = super.parseCommentReferencesInText(commentToken, start, end);
+    indent--;
+    return result;
+  }
+
+  int findReferenceEnd(String comment, int index, int end) {
+    doPrint('findReferenceEnd(' '$comment, ' '$index, ' '$end)');
+    indent++;
+    var result = super.findReferenceEnd(comment, index, end);
+    indent--;
+    return result;
+  }
+
+  bool parseOneCommentReference(Token token, int referenceOffset) {
+    doPrint('parseOneCommentReference(' '$token, ' '$referenceOffset)');
+    indent++;
+    var result = super.parseOneCommentReference(token, referenceOffset);
+    indent--;
+    return result;
+  }
+
+  void parseOneCommentReferenceRest(
+      Token begin,
+      int referenceOffset,
+      Token newKeyword,
+      Token prefix,
+      Token period,
+      Token identifierOrOperator) {
+    doPrint('parseOneCommentReferenceRest('
+        '$begin, '
+        '$referenceOffset, '
+        '$newKeyword, '
+        '$prefix, '
+        '$period, '
+        '$identifierOrOperator)');
+    indent++;
+    var result = super.parseOneCommentReferenceRest(begin, referenceOffset,
+        newKeyword, prefix, period, identifierOrOperator);
+    indent--;
+    return result;
+  }
+
+  bool isLinkText(String comment, int rightIndex) {
+    doPrint('isLinkText(' '$comment, ' '$rightIndex)');
+    indent++;
+    var result = super.isLinkText(comment, rightIndex);
+    indent--;
+    return result;
+  }
+}
diff --git a/pkg/front_end/test/parser_test_parser_creator.dart b/pkg/front_end/test/parser_test_parser_creator.dart
new file mode 100644
index 0000000..2079d47
--- /dev/null
+++ b/pkg/front_end/test/parser_test_parser_creator.dart
@@ -0,0 +1,240 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:front_end/src/fasta/parser.dart';
+import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fasta/parser/listener.dart';
+import 'package:front_end/src/fasta/parser/member_kind.dart';
+import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart';
+import 'package:front_end/src/scanner/token.dart';
+import 'package:dart_style/dart_style.dart' show DartFormatter;
+
+StringSink out;
+
+main(List<String> args) {
+  if (args.contains("--stdout")) {
+    out = stdout;
+  } else {
+    out = new StringBuffer();
+  }
+
+  File f = new File.fromUri(
+      Platform.script.resolve("../lib/src/fasta/parser/parser.dart"));
+  List<int> rawBytes = f.readAsBytesSync();
+
+  Uint8List bytes = new Uint8List(rawBytes.length + 1);
+  bytes.setRange(0, rawBytes.length, rawBytes);
+
+  Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
+  Token firstToken = scanner.tokenize();
+
+  out.write("""
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/fasta/parser/listener.dart' show Listener;
+import 'package:front_end/src/fasta/parser/parser.dart' show Parser;
+import 'package:front_end/src/scanner/token.dart';
+import 'package:front_end/src/fasta/fasta_codes.dart';
+import 'package:front_end/src/fasta/scanner.dart';
+import 'package:front_end/src/fasta/parser/assert.dart';
+import 'package:front_end/src/fasta/parser/declaration_kind.dart';
+import 'package:front_end/src/fasta/parser/directive_context.dart';
+import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fasta/parser/identifier_context.dart';
+import 'package:front_end/src/fasta/parser/member_kind.dart';
+import 'package:front_end/src/fasta/parser/token_stream_rewriter.dart';
+import 'package:front_end/src/fasta/parser/type_info.dart';
+
+// THIS FILE IS AUTO GENERATED BY 'test/parser_test_parser_creator.dart'
+
+class TestParser extends Parser {
+  TestParser(Listener listener) : super(listener);
+
+  int indent = 0;
+  StringBuffer sb = new StringBuffer();
+
+  void doPrint(String s) {
+    sb.writeln(("  " * indent) + s);
+  }
+""");
+
+  ParserCreatorListener listener = new ParserCreatorListener();
+  ClassMemberParser parser = new ClassMemberParser(listener);
+  parser.parseUnit(firstToken);
+
+  out.writeln("}");
+
+  if (out is StringBuffer) {
+    stdout.write(new DartFormatter().format("$out"));
+  }
+}
+
+class ParserCreatorListener extends Listener {
+  bool insideParserClass = false;
+  String currentMethodName;
+  List<String> parameters = <String>[];
+  List<String> parametersNamed = <String>[];
+
+  void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
+    if (name.lexeme == "Parser") insideParserClass = true;
+  }
+
+  void endClassDeclaration(Token beginToken, Token endToken) {
+    insideParserClass = false;
+  }
+
+  void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
+      Token varFinalOrConst, Token getOrSet, Token name) {
+    currentMethodName = name.lexeme;
+  }
+
+  void endClassConstructor(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    parameters.clear();
+    parametersNamed.clear();
+    currentMethodName = null;
+  }
+
+  void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    if (insideParserClass && !currentMethodName.startsWith("_")) {
+      Token token = beginToken;
+      Token latestToken;
+      out.write("  ");
+      while (true) {
+        if (troubleParameterTokens.containsKey(token)) {
+          if (latestToken != null && latestToken.charEnd < token.charOffset) {
+            out.write(" ");
+          }
+          out.write("dynamic");
+          token = troubleParameterTokens[token];
+        }
+        if (latestToken != null && latestToken.charEnd < token.charOffset) {
+          out.write(" ");
+        }
+        if (token is SimpleToken && token.type == TokenType.FUNCTION) {
+          // Don't write out the '=>'.
+          out.write("{");
+          break;
+        }
+        out.write(token.lexeme);
+        if (token is BeginToken &&
+            token.type == TokenType.OPEN_CURLY_BRACKET &&
+            (beginParam == null ||
+                beginParam.endGroup == endToken ||
+                token.charOffset > beginParam.endGroup.charOffset)) {
+          break;
+        }
+        if (token == endToken) {
+          throw token.runtimeType;
+        }
+        latestToken = token;
+        token = token.next;
+      }
+
+      out.write("\n    ");
+      out.write("doPrint('$currentMethodName(");
+      String separator = "";
+      for (int i = 0; i < parameters.length; i++) {
+        out.write(separator);
+        out.write(r"' '$");
+        out.write(parameters[i]);
+        separator = ", ";
+      }
+      for (int i = 0; i < parametersNamed.length; i++) {
+        out.write(separator);
+        out.write("' '");
+        out.write(parametersNamed[i]);
+        out.write(r": $");
+        out.write(parametersNamed[i]);
+        separator = ", ";
+      }
+      out.write(")');\n    ");
+
+      out.write("indent++;\n    ");
+      out.write("var result = super.$currentMethodName");
+      if (getOrSet != null && getOrSet.lexeme == "get") {
+        // no parens
+        out.write(";\n    ");
+      } else {
+        out.write("(");
+        String separator = "";
+        for (int i = 0; i < parameters.length; i++) {
+          out.write(separator);
+          out.write(parameters[i]);
+          separator = ", ";
+        }
+        for (int i = 0; i < parametersNamed.length; i++) {
+          out.write(separator);
+          out.write(parametersNamed[i]);
+          out.write(": ");
+          out.write(parametersNamed[i]);
+          separator = ", ";
+        }
+        out.write(");\n    ");
+      }
+      out.write("indent--;\n    ");
+      out.write("return result;\n  ");
+      out.write("}");
+      out.write("\n\n");
+    }
+    parameters.clear();
+    parametersNamed.clear();
+    currentMethodName = null;
+  }
+
+  int formalParametersNestLevel = 0;
+  void beginFormalParameters(Token token, MemberKind kind) {
+    formalParametersNestLevel++;
+  }
+
+  void endFormalParameters(
+      int count, Token beginToken, Token endToken, MemberKind kind) {
+    formalParametersNestLevel--;
+  }
+
+  Token currentFormalParameterToken;
+
+  void beginFormalParameter(Token token, MemberKind kind, Token requiredToken,
+      Token covariantToken, Token varFinalOrConst) {
+    if (formalParametersNestLevel == 1) {
+      currentFormalParameterToken = token;
+    }
+  }
+
+  Map<Token, Token> troubleParameterTokens = {};
+
+  void handleIdentifier(Token token, IdentifierContext context) {
+    if (formalParametersNestLevel > 0 && token.lexeme.startsWith("_")) {
+      troubleParameterTokens[currentFormalParameterToken] = null;
+    }
+  }
+
+  void endFormalParameter(
+      Token thisKeyword,
+      Token periodAfterThis,
+      Token nameToken,
+      Token initializerStart,
+      Token initializerEnd,
+      FormalParameterKind kind,
+      MemberKind memberKind) {
+    if (formalParametersNestLevel != 1) {
+      return;
+    }
+    if (troubleParameterTokens.containsKey(currentFormalParameterToken)) {
+      troubleParameterTokens[currentFormalParameterToken] = nameToken;
+    }
+    currentFormalParameterToken = null;
+    if (kind == FormalParameterKind.optionalNamed) {
+      parametersNamed.add(nameToken.lexeme);
+    } else {
+      parameters.add(nameToken.lexeme);
+    }
+  }
+}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 351b53d..aa8e429 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -509,6 +509,7 @@
 moves
 msg
 murmur
+mus
 n
 na
 nameless
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 40d83cd..493e5cd 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -464,6 +464,7 @@
 compare
 comparing
 comparison
+comparisons
 compatibility
 compatible
 compilation
@@ -567,6 +568,7 @@
 continued
 continues
 continuing
+contraposition
 contrast
 contravariance
 contravariant
@@ -1413,6 +1415,7 @@
 interpreting
 intersect
 intersection
+intertwined
 into
 intrinsic
 introduce
@@ -1887,6 +1890,7 @@
 output
 outside
 over
+overall
 overflow
 overloadable
 overloaded
@@ -2697,6 +2701,7 @@
 terminating
 termination
 terminology
+terms
 ternary
 test
 testcase
@@ -2742,6 +2747,7 @@
 thumb
 thus
 time
+timeline
 times
 tip
 to
@@ -2802,6 +2808,7 @@
 triplet
 triplets
 trivial
+trouble
 true
 truly
 truncate
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
index 8789584..c02e68e 100644
--- a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
@@ -1,11 +1,10 @@
 Errors: {
   org-dartlang-debug:synthetic_debug_expression:2:13: Error: A value of type 'A<dynamic>' can't be assigned to a variable of type 'T'.
    - 'A' is from 'pkg/front_end/testcases/expression/main.dart'.
-  Try changing the type of the left hand side, or casting the right hand side to 'T'.
     T k = new A();
               ^
 }
 method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
   return () → dart.core::Null? {
-    main::A::debugExpr::T* k = let final<BottomType> #t1 = invalid-expression "org-dartlang-debug:synthetic_debug_expression:2:13: Error: A value of type 'A<dynamic>' can't be assigned to a variable of type 'T'.\n - 'A' is from 'pkg/front_end/testcases/expression/main.dart'.\nTry changing the type of the left hand side, or casting the right hand side to 'T'.\n  T k = new A();\n            ^" in new main::A::•<dynamic>() as{TypeError} <BottomType>;
+    main::A::debugExpr::T* k = let final<BottomType> #t1 = invalid-expression "org-dartlang-debug:synthetic_debug_expression:2:13: Error: A value of type 'A<dynamic>' can't be assigned to a variable of type 'T'.\n - 'A' is from 'pkg/front_end/testcases/expression/main.dart'.\n  T k = new A();\n            ^" in new main::A::•<dynamic>() as{TypeError} <BottomType>;
   };
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
index b551a0a..c99820d 100644
--- a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
@@ -9,32 +9,32 @@
 //   classA.method();
 //          ^^^^^^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:24:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:24:21: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension(classA).method();
-//   ^
+//                     ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:25:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:25:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classA).method();
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:31:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:31:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classB).method();
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
@@ -59,42 +59,42 @@
 //   genericMethod<S extends B>(S s) {}
 //                 ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:37:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:37:21: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension(classB).genericMethod(a);
-//   ^
+//                     ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
 //   genericMethod<S extends B>(S s) {}
 //                 ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classB).genericMethod(a);
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classB).genericMethod(a);
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
 //   genericMethod<S extends B>(S s) {}
 //                 ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:43:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:43:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<B>(classB).genericMethod(a);
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
 //   genericMethod<S extends B>(S s) {}
 //                 ^
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
index b551a0a..c99820d 100644
--- a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
@@ -9,32 +9,32 @@
 //   classA.method();
 //          ^^^^^^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:24:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:24:21: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension(classA).method();
-//   ^
+//                     ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:25:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:25:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classA).method();
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:31:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:31:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classB).method();
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
@@ -59,42 +59,42 @@
 //   genericMethod<S extends B>(S s) {}
 //                 ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:37:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:37:21: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension(classB).genericMethod(a);
-//   ^
+//                     ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
 //   genericMethod<S extends B>(S s) {}
 //                 ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classB).genericMethod(a);
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
 // extension Extension<T extends B> on Class<T> {
 //                     ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<A>(classB).genericMethod(a);
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
 //   genericMethod<S extends B>(S s) {}
 //                 ^
 //
-// pkg/front_end/testcases/extensions/check_bounds.dart:43:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+// pkg/front_end/testcases/extensions/check_bounds.dart:43:24: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
 //  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 //  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   Extension<B>(classB).genericMethod(a);
-//   ^
+//                        ^
 // pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
 //   genericMethod<S extends B>(S s) {}
 //                 ^
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart b/pkg/front_end/testcases/extensions/conflict_with_object.dart
new file mode 100644
index 0000000..4d25f0e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension Extension on String {
+  int get noSuchMethod => 42;
+  void set hashCode(int value) {}
+  int runtimeType() {}
+  operator ==(other) => false;
+  static String toString() => 'Foo';
+}
+
+main() {
+  int value;
+  expect(true, "".noSuchMethod is Function);
+  value = Extension("").noSuchMethod;
+  Extension("").hashCode = 42;
+  expect(true, "".runtimeType is Type);
+  expect(true, Extension("").runtimeType is Function);
+  value = Extension("").runtimeType();
+  expect(true, "" == "");
+  expect('Foo', Extension.toString());
+}
+
+errors() {
+  int value;
+  value = "".noSuchMethod;
+  "".hashCode = 42;
+  value = "".runtimeType;
+}
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Mismatch: expected=$expected, actual=$actual';
+  }
+}
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect
new file mode 100644
index 0000000..4d46ff2
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.outline.expect
@@ -0,0 +1,53 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:6:11: Error: This extension member conflicts with Object member 'noSuchMethod'.
+//   int get noSuchMethod => 42;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:8:7: Error: This extension member conflicts with Object member 'runtimeType'.
+//   int runtimeType() {}
+//       ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:9:12: Error: This extension member conflicts with Object member '=='.
+//   operator ==(other) => false;
+//            ^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:10:17: Error: This extension member conflicts with Object member 'toString'.
+//   static String toString() => 'Foo';
+//                 ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:7:12: Error: This extension member conflicts with Object member 'hashCode'.
+//   void set hashCode(int value) {}
+//            ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension on core::String* {
+  get noSuchMethod = self::Extension|get#noSuchMethod;
+  method runtimeType = self::Extension|runtimeType;
+  tearoff runtimeType = self::Extension|get#runtimeType;
+  operator == = self::Extension|==;
+  static method toString = self::Extension|toString;
+  set hashCode = self::Extension|set#hashCode;
+}
+static method Extension|get#noSuchMethod(final core::String* #this) → core::int*
+  ;
+static method Extension|set#hashCode(final core::String* #this, core::int* value) → void
+  ;
+static method Extension|runtimeType(final core::String* #this) → core::int*
+  ;
+static method Extension|get#runtimeType(final core::String* #this) → () →* core::int*
+  return () → core::int* => self::Extension|runtimeType(#this);
+static method Extension|==(final core::String* #this, dynamic other) → dynamic
+  ;
+static method Extension|toString() → core::String*
+  ;
+static method main() → dynamic
+  ;
+static method errors() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect
new file mode 100644
index 0000000..891feb9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.expect
@@ -0,0 +1,91 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:6:11: Error: This extension member conflicts with Object member 'noSuchMethod'.
+//   int get noSuchMethod => 42;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:8:7: Error: This extension member conflicts with Object member 'runtimeType'.
+//   int runtimeType() {}
+//       ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:9:12: Error: This extension member conflicts with Object member '=='.
+//   operator ==(other) => false;
+//            ^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:10:17: Error: This extension member conflicts with Object member 'toString'.
+//   static String toString() => 'Foo';
+//                 ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:7:12: Error: This extension member conflicts with Object member 'hashCode'.
+//   void set hashCode(int value) {}
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:27:14: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'int'.
+//  - 'Invocation' is from 'dart:core'.
+//   value = "".noSuchMethod;
+//              ^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:28:6: Error: The setter 'hashCode' isn't defined for the class 'String'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'hashCode'.
+//   "".hashCode = 42;
+//      ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:29:14: Error: A value of type 'Type' can't be assigned to a variable of type 'int'.
+//  - 'Type' is from 'dart:core'.
+//   value = "".runtimeType;
+//              ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension on core::String* {
+  get noSuchMethod = self::Extension|get#noSuchMethod;
+  method runtimeType = self::Extension|runtimeType;
+  tearoff runtimeType = self::Extension|get#runtimeType;
+  operator == = self::Extension|==;
+  static method toString = self::Extension|toString;
+  set hashCode = self::Extension|set#hashCode;
+}
+static method Extension|get#noSuchMethod(final core::String* #this) → core::int*
+  return 42;
+static method Extension|set#hashCode(final core::String* #this, core::int* value) → void {}
+static method Extension|runtimeType(final core::String* #this) → core::int* {}
+static method Extension|get#runtimeType(final core::String* #this) → () →* core::int*
+  return () → core::int* => self::Extension|runtimeType(#this);
+static method Extension|==(final core::String* #this, dynamic other) → dynamic
+  return false;
+static method Extension|toString() → core::String*
+  return "Foo";
+static method main() → dynamic {
+  core::int* value;
+  self::expect(true, "".{core::Object::noSuchMethod} is core::Function*);
+  value = self::Extension|get#noSuchMethod("");
+  self::Extension|set#hashCode("", 42);
+  self::expect(true, "".{core::Object::runtimeType} is core::Type*);
+  self::expect(true, self::Extension|get#runtimeType("") is core::Function*);
+  value = self::Extension|runtimeType("");
+  self::expect(true, "".{core::String::==}(""));
+  self::expect("Foo", self::Extension|toString());
+}
+static method errors() → dynamic {
+  core::int* value;
+  value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/conflict_with_object.dart:27:14: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'int'.
+ - 'Invocation' is from 'dart:core'.
+  value = \"\".noSuchMethod;
+             ^" in "".{core::Object::noSuchMethod} as{TypeError} core::int*;
+  invalid-expression "pkg/front_end/testcases/extensions/conflict_with_object.dart:28:6: Error: The setter 'hashCode' isn't defined for the class 'String'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'hashCode'.
+  \"\".hashCode = 42;
+     ^^^^^^^^";
+  value = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/conflict_with_object.dart:29:14: Error: A value of type 'Type' can't be assigned to a variable of type 'int'.
+ - 'Type' is from 'dart:core'.
+  value = \"\".runtimeType;
+             ^" in "".{core::Object::runtimeType} as{TypeError} core::int*;
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Mismatch: expected=${expected}, actual=${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect
new file mode 100644
index 0000000..891feb9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.strong.transformed.expect
@@ -0,0 +1,91 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:6:11: Error: This extension member conflicts with Object member 'noSuchMethod'.
+//   int get noSuchMethod => 42;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:8:7: Error: This extension member conflicts with Object member 'runtimeType'.
+//   int runtimeType() {}
+//       ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:9:12: Error: This extension member conflicts with Object member '=='.
+//   operator ==(other) => false;
+//            ^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:10:17: Error: This extension member conflicts with Object member 'toString'.
+//   static String toString() => 'Foo';
+//                 ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:7:12: Error: This extension member conflicts with Object member 'hashCode'.
+//   void set hashCode(int value) {}
+//            ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:27:14: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'int'.
+//  - 'Invocation' is from 'dart:core'.
+//   value = "".noSuchMethod;
+//              ^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:28:6: Error: The setter 'hashCode' isn't defined for the class 'String'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'hashCode'.
+//   "".hashCode = 42;
+//      ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflict_with_object.dart:29:14: Error: A value of type 'Type' can't be assigned to a variable of type 'int'.
+//  - 'Type' is from 'dart:core'.
+//   value = "".runtimeType;
+//              ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension on core::String* {
+  get noSuchMethod = self::Extension|get#noSuchMethod;
+  method runtimeType = self::Extension|runtimeType;
+  tearoff runtimeType = self::Extension|get#runtimeType;
+  operator == = self::Extension|==;
+  static method toString = self::Extension|toString;
+  set hashCode = self::Extension|set#hashCode;
+}
+static method Extension|get#noSuchMethod(final core::String* #this) → core::int*
+  return 42;
+static method Extension|set#hashCode(final core::String* #this, core::int* value) → void {}
+static method Extension|runtimeType(final core::String* #this) → core::int* {}
+static method Extension|get#runtimeType(final core::String* #this) → () →* core::int*
+  return () → core::int* => self::Extension|runtimeType(#this);
+static method Extension|==(final core::String* #this, dynamic other) → dynamic
+  return false;
+static method Extension|toString() → core::String*
+  return "Foo";
+static method main() → dynamic {
+  core::int* value;
+  self::expect(true, "".{core::Object::noSuchMethod} is core::Function*);
+  value = self::Extension|get#noSuchMethod("");
+  self::Extension|set#hashCode("", 42);
+  self::expect(true, "".{core::Object::runtimeType} is core::Type*);
+  self::expect(true, self::Extension|get#runtimeType("") is core::Function*);
+  value = self::Extension|runtimeType("");
+  self::expect(true, "".{core::String::==}(""));
+  self::expect("Foo", self::Extension|toString());
+}
+static method errors() → dynamic {
+  core::int* value;
+  value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/conflict_with_object.dart:27:14: Error: A value of type 'dynamic Function(Invocation)' can't be assigned to a variable of type 'int'.
+ - 'Invocation' is from 'dart:core'.
+  value = \"\".noSuchMethod;
+             ^" in "".{core::Object::noSuchMethod} as{TypeError} core::int*;
+  invalid-expression "pkg/front_end/testcases/extensions/conflict_with_object.dart:28:6: Error: The setter 'hashCode' isn't defined for the class 'String'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'hashCode'.
+  \"\".hashCode = 42;
+     ^^^^^^^^";
+  value = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/conflict_with_object.dart:29:14: Error: A value of type 'Type' can't be assigned to a variable of type 'int'.
+ - 'Type' is from 'dart:core'.
+  value = \"\".runtimeType;
+             ^" in "".{core::Object::runtimeType} as{TypeError} core::int*;
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Mismatch: expected=${expected}, actual=${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.type_promotion.expect
new file mode 100644
index 0000000..3748577
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.type_promotion.expect
@@ -0,0 +1,12 @@
+pkg/front_end/testcases/extensions/conflict_with_object.dart:16:9: Context: Write to value@422
+  value = Extension("").noSuchMethod;
+        ^
+pkg/front_end/testcases/extensions/conflict_with_object.dart:20:9: Context: Write to value@422
+  value = Extension("").runtimeType();
+        ^
+pkg/front_end/testcases/extensions/conflict_with_object.dart:27:9: Context: Write to value@762
+  value = "".noSuchMethod;
+        ^
+pkg/front_end/testcases/extensions/conflict_with_object.dart:29:9: Context: Write to value@762
+  value = "".runtimeType;
+        ^
diff --git a/pkg/front_end/testcases/extensions/default_values.dart b/pkg/front_end/testcases/extensions/default_values.dart
index 0b08f6d..eb948c2 100644
--- a/pkg/front_end/testcases/extensions/default_values.dart
+++ b/pkg/front_end/testcases/extensions/default_values.dart
@@ -28,9 +28,8 @@
   expect(123, tearOff3());
 }
 
-
 expect(expected, actual) {
   if (expected != actual) {
     throw 'Mismatch: expected=$expected, actual=$actual';
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
index 569b235..7711d44 100644
--- a/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/extensions/extension_setter_error.dart:13:41: Error: A value of type 'GenericClass<int>' can't be assigned to a variable of type 'GenericClass<double>'.
 //  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/extension_setter_error.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'GenericClass<double>'.
 //   expect(null, GenericExtension<double>(genericClass).setter = null);
 //                                         ^
 //
@@ -24,7 +23,6 @@
   self::GenericClass<core::int*>* genericClass = new self::GenericClass::•<core::int*>();
   self::expect(null, let final self::GenericClass<core::int*>* #t1 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/extension_setter_error.dart:13:41: Error: A value of type 'GenericClass<int>' can't be assigned to a variable of type 'GenericClass<double>'.
  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/extension_setter_error.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'GenericClass<double>'.
   expect(null, GenericExtension<double>(genericClass).setter = null);
                                         ^" in genericClass as{TypeError} self::GenericClass<core::double*>* in let final core::Null? #t3 = null in let final void #t4 = self::GenericExtension|set#setter<core::double*>(#t1, #t3) in #t3);
 }
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart
new file mode 100644
index 0000000..72989b9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Regression test for missing substitution of type variable used in the
+/// return type of a generic method on a generic extension.
+
+class Class<T> {}
+
+extension Extension<T> on Class<T> {
+  R method<R>(T t) => null;
+}
+
+main() {
+  new Class<int>().method(0)?.toString();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect
new file mode 100644
index 0000000..a666b12
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.outline.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    ;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
+  ;
+static method Extension|get#method<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
+  return <R extends core::Object* = dynamic>(self::Extension|get#method::T* t) → R* => self::Extension|method<self::Extension|get#method::T*, R*>(#this, t);
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect
new file mode 100644
index 0000000..5de03f0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
+  return null;
+static method Extension|get#method<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
+  return <R extends core::Object* = dynamic>(self::Extension|get#method::T* t) → R* => self::Extension|method<self::Extension|get#method::T*, R*>(#this, t);
+static method main() → dynamic {
+  let final dynamic #t1 = self::Extension|method<core::int*, dynamic>(new self::Class::•<core::int*>(), 0) in #t1.{core::Object::==}(null) ?{core::String*} null : #t1.{core::Object::toString}();
+}
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect
new file mode 100644
index 0000000..5de03f0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method Extension|method<T extends core::Object* = dynamic, R extends core::Object* = dynamic>(final self::Class<self::Extension|method::T*>* #this, self::Extension|method::T* t) → self::Extension|method::R*
+  return null;
+static method Extension|get#method<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → <R extends core::Object* = dynamic>(self::Extension|get#method::T*) →* R*
+  return <R extends core::Object* = dynamic>(self::Extension|get#method::T* t) → R* => self::Extension|method<self::Extension|get#method::T*, R*>(#this, t);
+static method main() → dynamic {
+  let final dynamic #t1 = self::Extension|method<core::int*, dynamic>(new self::Class::•<core::int*>(), 0) in #t1.{core::Object::==}(null) ?{core::String*} null : #t1.{core::Object::toString}();
+}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect
index 86beef5..ab40325 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect
@@ -22,36 +22,36 @@
 //   Extension<int>(c1).method(null);
 //   ^^^^^^^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:3: Error: Getter not found: 'foo'.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:17: Error: Getter not found: 'foo'.
 //   Extension(c1).foo;
-//   ^^^
+//                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:3: Error: Setter not found: 'foo'.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:17: Error: Setter not found: 'foo'.
 //   Extension(c1).foo = null;
-//   ^^^
+//                 ^^^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
 //   Extension(c1).foo();
 //                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
 //   Extension(c1).method();
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:3: Error: Too many positional arguments: 2 allowed, but 3 found.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
 // Try removing the extra positional arguments.
 //   Extension(c1).method(1, 2);
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:3: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
 //   Extension(c1).method(a: 1);
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
@@ -63,9 +63,9 @@
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
 //   Extension(c1).method<int>(null);
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
@@ -108,19 +108,16 @@
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:28:13: Error: The argument type 'String' can't be assigned to the parameter type 'Class'.
 //  - 'Class' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-// Try changing the type of the parameter, or casting the argument to 'Class'.
 //   Extension(s).method(null);
 //             ^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:51:20: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<dynamic>'.
 //  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-// Try changing the type of the parameter, or casting the argument to 'GenericClass<dynamic>'.
 //   GenericExtension(s).method();
 //                    ^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:52:25: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<int>'.
 //  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-// Try changing the type of the parameter, or casting the argument to 'GenericClass<int>'.
 //   GenericExtension<int>(s).method();
 //                         ^
 //
@@ -171,34 +168,33 @@
   ^^^^^^^^^".method(null);
   self::Extension|method(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:28:13: Error: The argument type 'String' can't be assigned to the parameter type 'Class'.
  - 'Class' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-Try changing the type of the parameter, or casting the argument to 'Class'.
   Extension(s).method(null);
             ^" in s as{TypeError} self::Class*, null);
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:3: Error: Getter not found: 'foo'.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:17: Error: Getter not found: 'foo'.
   Extension(c1).foo;
-  ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:3: Error: Setter not found: 'foo'.
+                ^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:17: Error: Setter not found: 'foo'.
   Extension(c1).foo = null;
-  ^^^";
+                ^^^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
                 ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
   Extension(c1).method();
-  ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:3: Error: Too many positional arguments: 2 allowed, but 3 found.
+                ^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
 Try removing the extra positional arguments.
   Extension(c1).method(1, 2);
-  ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:3: Error: Too few positional arguments: 2 required, 1 given.
+                ^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
   Extension(c1).method(a: 1);
-  ^";
+                ^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
   Extension(c1).method(1, a: 2);
                           ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
   Extension(c1).method<int>(null);
-  ^";
+                ^";
   self::GenericClass<core::int*>* c2 = new self::GenericClass::•<core::int*>();
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:42:3: Error: Explicit extension application requires exactly 1 positional argument.
   GenericExtension().method();
@@ -229,12 +225,10 @@
   ^^^^^^^^^^^^^^^^".method();
   self::GenericExtension|method<dynamic>(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:51:20: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<dynamic>'.
  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-Try changing the type of the parameter, or casting the argument to 'GenericClass<dynamic>'.
   GenericExtension(s).method();
                    ^" in s as{TypeError} self::GenericClass<dynamic>*);
   self::GenericExtension|method<core::int*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:52:25: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<int>'.
  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-Try changing the type of the parameter, or casting the argument to 'GenericClass<int>'.
   GenericExtension<int>(s).method();
                         ^" in s as{TypeError} self::GenericClass<core::int*>*);
 }
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect
index 86beef5..ab40325 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect
@@ -22,36 +22,36 @@
 //   Extension<int>(c1).method(null);
 //   ^^^^^^^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:3: Error: Getter not found: 'foo'.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:17: Error: Getter not found: 'foo'.
 //   Extension(c1).foo;
-//   ^^^
+//                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:3: Error: Setter not found: 'foo'.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:17: Error: Setter not found: 'foo'.
 //   Extension(c1).foo = null;
-//   ^^^
+//                 ^^^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
 //   Extension(c1).foo();
 //                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
 //   Extension(c1).method();
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:3: Error: Too many positional arguments: 2 allowed, but 3 found.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
 // Try removing the extra positional arguments.
 //   Extension(c1).method(1, 2);
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:3: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
 //   Extension(c1).method(a: 1);
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
@@ -63,9 +63,9 @@
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
 //   Extension(c1).method<int>(null);
-//   ^
+//                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
@@ -108,19 +108,16 @@
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:28:13: Error: The argument type 'String' can't be assigned to the parameter type 'Class'.
 //  - 'Class' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-// Try changing the type of the parameter, or casting the argument to 'Class'.
 //   Extension(s).method(null);
 //             ^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:51:20: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<dynamic>'.
 //  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-// Try changing the type of the parameter, or casting the argument to 'GenericClass<dynamic>'.
 //   GenericExtension(s).method();
 //                    ^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:52:25: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<int>'.
 //  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-// Try changing the type of the parameter, or casting the argument to 'GenericClass<int>'.
 //   GenericExtension<int>(s).method();
 //                         ^
 //
@@ -171,34 +168,33 @@
   ^^^^^^^^^".method(null);
   self::Extension|method(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:28:13: Error: The argument type 'String' can't be assigned to the parameter type 'Class'.
  - 'Class' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-Try changing the type of the parameter, or casting the argument to 'Class'.
   Extension(s).method(null);
             ^" in s as{TypeError} self::Class*, null);
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:3: Error: Getter not found: 'foo'.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:29:17: Error: Getter not found: 'foo'.
   Extension(c1).foo;
-  ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:3: Error: Setter not found: 'foo'.
+                ^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:17: Error: Setter not found: 'foo'.
   Extension(c1).foo = null;
-  ^^^";
+                ^^^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
                 ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
   Extension(c1).method();
-  ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:3: Error: Too many positional arguments: 2 allowed, but 3 found.
+                ^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
 Try removing the extra positional arguments.
   Extension(c1).method(1, 2);
-  ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:3: Error: Too few positional arguments: 2 required, 1 given.
+                ^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
   Extension(c1).method(a: 1);
-  ^";
+                ^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
   Extension(c1).method(1, a: 2);
                           ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
   Extension(c1).method<int>(null);
-  ^";
+                ^";
   self::GenericClass<core::int*>* c2 = new self::GenericClass::•<core::int*>();
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:42:3: Error: Explicit extension application requires exactly 1 positional argument.
   GenericExtension().method();
@@ -229,12 +225,10 @@
   ^^^^^^^^^^^^^^^^".method();
   self::GenericExtension|method<dynamic>(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:51:20: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<dynamic>'.
  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-Try changing the type of the parameter, or casting the argument to 'GenericClass<dynamic>'.
   GenericExtension(s).method();
                    ^" in s as{TypeError} self::GenericClass<dynamic>*);
   self::GenericExtension|method<core::int*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:52:25: Error: The argument type 'String' can't be assigned to the parameter type 'GenericClass<int>'.
  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/invalid_explicit_access.dart'.
-Try changing the type of the parameter, or casting the argument to 'GenericClass<int>'.
   GenericExtension<int>(s).method();
                         ^" in s as{TypeError} self::GenericClass<core::int*>*);
 }
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart
new file mode 100644
index 0000000..3fdcc7d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension Extension on String {
+  static method() {}
+  static get getter => null;
+  static set setter(_) {}
+  static get property => null;
+  static set property(_) {}
+  static var field;
+}
+
+main() {}
+
+errors() {
+  String s = "";
+  Extension(s).method();
+  Extension(s).method;
+  Extension(s).method = 42;
+  Extension(s).getter;
+  Extension(s).getter = 42;
+  Extension(s).setter;
+  Extension(s).setter = 42;
+  Extension(s).property;
+  Extension(s).property = 42;
+  Extension(s).field;
+  Extension(s).field = 42;
+}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.outline.expect
new file mode 100644
index 0000000..76899b5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.outline.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+extension Extension on core::String* {
+  static method method = self::Extension|method;
+  static get getter = get self::Extension|getter;
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static set setter = set self::Extension|setter;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static method Extension|method() → dynamic
+  ;
+static get Extension|getter() → dynamic
+  ;
+static set Extension|setter(dynamic _) → void
+  ;
+static get Extension|property() → dynamic
+  ;
+static set Extension|property(dynamic _) → void
+  ;
+static method main() → dynamic
+  ;
+static method errors() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.strong.expect
new file mode 100644
index 0000000..6317f7b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.strong.expect
@@ -0,0 +1,104 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:18:16: Error: Method not found: 'method'.
+//   Extension(s).method();
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:19:16: Error: Getter not found: 'method'.
+//   Extension(s).method;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:20:16: Error: Setter not found: 'method'.
+//   Extension(s).method = 42;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:21:16: Error: Getter not found: 'getter'.
+//   Extension(s).getter;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:22:16: Error: Setter not found: 'getter'.
+//   Extension(s).getter = 42;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:23:16: Error: Getter not found: 'setter'.
+//   Extension(s).setter;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:24:16: Error: Setter not found: 'setter'.
+//   Extension(s).setter = 42;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:25:16: Error: Getter not found: 'property'.
+//   Extension(s).property;
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:26:16: Error: Setter not found: 'property'.
+//   Extension(s).property = 42;
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:27:16: Error: Getter not found: 'field'.
+//   Extension(s).field;
+//                ^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:28:16: Error: Setter not found: 'field'.
+//   Extension(s).field = 42;
+//                ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension on core::String* {
+  static method method = self::Extension|method;
+  static get getter = get self::Extension|getter;
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static set setter = set self::Extension|setter;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static method Extension|method() → dynamic {}
+static get Extension|getter() → dynamic
+  return null;
+static set Extension|setter(dynamic _) → void {}
+static get Extension|property() → dynamic
+  return null;
+static set Extension|property(dynamic _) → void {}
+static method main() → dynamic {}
+static method errors() → dynamic {
+  core::String* s = "";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:18:16: Error: Method not found: 'method'.
+  Extension(s).method();
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:19:16: Error: Getter not found: 'method'.
+  Extension(s).method;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:20:16: Error: Setter not found: 'method'.
+  Extension(s).method = 42;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:21:16: Error: Getter not found: 'getter'.
+  Extension(s).getter;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:22:16: Error: Setter not found: 'getter'.
+  Extension(s).getter = 42;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:23:16: Error: Getter not found: 'setter'.
+  Extension(s).setter;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:24:16: Error: Setter not found: 'setter'.
+  Extension(s).setter = 42;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:25:16: Error: Getter not found: 'property'.
+  Extension(s).property;
+               ^^^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:26:16: Error: Setter not found: 'property'.
+  Extension(s).property = 42;
+               ^^^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:27:16: Error: Getter not found: 'field'.
+  Extension(s).field;
+               ^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:28:16: Error: Setter not found: 'field'.
+  Extension(s).field = 42;
+               ^^^^^";
+}
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..6317f7b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.strong.transformed.expect
@@ -0,0 +1,104 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:18:16: Error: Method not found: 'method'.
+//   Extension(s).method();
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:19:16: Error: Getter not found: 'method'.
+//   Extension(s).method;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:20:16: Error: Setter not found: 'method'.
+//   Extension(s).method = 42;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:21:16: Error: Getter not found: 'getter'.
+//   Extension(s).getter;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:22:16: Error: Setter not found: 'getter'.
+//   Extension(s).getter = 42;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:23:16: Error: Getter not found: 'setter'.
+//   Extension(s).setter;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:24:16: Error: Setter not found: 'setter'.
+//   Extension(s).setter = 42;
+//                ^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:25:16: Error: Getter not found: 'property'.
+//   Extension(s).property;
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:26:16: Error: Setter not found: 'property'.
+//   Extension(s).property = 42;
+//                ^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:27:16: Error: Getter not found: 'field'.
+//   Extension(s).field;
+//                ^^^^^
+//
+// pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:28:16: Error: Setter not found: 'field'.
+//   Extension(s).field = 42;
+//                ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension on core::String* {
+  static method method = self::Extension|method;
+  static get getter = get self::Extension|getter;
+  static get property = get self::Extension|property;
+  static field field = self::Extension|field;
+  static set setter = set self::Extension|setter;
+  static set property = set self::Extension|property;
+}
+static field dynamic Extension|field;
+static method Extension|method() → dynamic {}
+static get Extension|getter() → dynamic
+  return null;
+static set Extension|setter(dynamic _) → void {}
+static get Extension|property() → dynamic
+  return null;
+static set Extension|property(dynamic _) → void {}
+static method main() → dynamic {}
+static method errors() → dynamic {
+  core::String* s = "";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:18:16: Error: Method not found: 'method'.
+  Extension(s).method();
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:19:16: Error: Getter not found: 'method'.
+  Extension(s).method;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:20:16: Error: Setter not found: 'method'.
+  Extension(s).method = 42;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:21:16: Error: Getter not found: 'getter'.
+  Extension(s).getter;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:22:16: Error: Setter not found: 'getter'.
+  Extension(s).getter = 42;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:23:16: Error: Getter not found: 'setter'.
+  Extension(s).setter;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:24:16: Error: Setter not found: 'setter'.
+  Extension(s).setter = 42;
+               ^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:25:16: Error: Getter not found: 'property'.
+  Extension(s).property;
+               ^^^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:26:16: Error: Setter not found: 'property'.
+  Extension(s).property = 42;
+               ^^^^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:27:16: Error: Getter not found: 'field'.
+  Extension(s).field;
+               ^^^^^";
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart:28:16: Error: Setter not found: 'field'.
+  Extension(s).field = 42;
+               ^^^^^";
+}
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
index 86c38ea..826d872 100644
--- a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
@@ -3,19 +3,16 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //     int Function(int) intId = getter;
 //                               ^
 //
 // pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
 //   num Function(num) numId = c.getter;
 //                               ^
 //
-// pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+// pkg/front_end/testcases/extensions/tear_offs.dart:31:45: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
 //   bool Function(bool) boolId = Extension(c).getter;
-//                                ^
+//                                             ^
 //
 import self as self;
 import "dart:core" as core;
@@ -47,7 +44,6 @@
   return () → dynamic => self::Extension|method(#this);
 static method Extension|errors(final self::Class* #this) → dynamic {
   (core::int*) →* core::int* intId = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
     int Function(int) intId = getter;
                               ^" in self::Extension|get#getter(#this) as{TypeError} (core::int*) →* core::int*;
 }
@@ -61,11 +57,9 @@
 static method errors() → dynamic {
   self::Class* c = new self::Class::•();
   (core::num*) →* core::num* numId = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
-Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
   num Function(num) numId = c.getter;
                               ^" in self::Extension|get#getter(c) as{TypeError} (core::num*) →* core::num*;
-  (core::bool*) →* core::bool* boolId = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+  (core::bool*) →* core::bool* boolId = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:31:45: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
   bool Function(bool) boolId = Extension(c).getter;
-                               ^" in self::Extension|get#getter(c) as{TypeError} (core::bool*) →* core::bool*;
+                                            ^" in self::Extension|get#getter(c) as{TypeError} (core::bool*) →* core::bool*;
 }
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
index 86c38ea..826d872 100644
--- a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
@@ -3,19 +3,16 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //     int Function(int) intId = getter;
 //                               ^
 //
 // pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
 //   num Function(num) numId = c.getter;
 //                               ^
 //
-// pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+// pkg/front_end/testcases/extensions/tear_offs.dart:31:45: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
 //   bool Function(bool) boolId = Extension(c).getter;
-//                                ^
+//                                             ^
 //
 import self as self;
 import "dart:core" as core;
@@ -47,7 +44,6 @@
   return () → dynamic => self::Extension|method(#this);
 static method Extension|errors(final self::Class* #this) → dynamic {
   (core::int*) →* core::int* intId = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
     int Function(int) intId = getter;
                               ^" in self::Extension|get#getter(#this) as{TypeError} (core::int*) →* core::int*;
 }
@@ -61,11 +57,9 @@
 static method errors() → dynamic {
   self::Class* c = new self::Class::•();
   (core::num*) →* core::num* numId = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
-Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
   num Function(num) numId = c.getter;
                               ^" in self::Extension|get#getter(c) as{TypeError} (core::num*) →* core::num*;
-  (core::bool*) →* core::bool* boolId = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+  (core::bool*) →* core::bool* boolId = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:31:45: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
   bool Function(bool) boolId = Extension(c).getter;
-                               ^" in self::Extension|get#getter(c) as{TypeError} (core::bool*) →* core::bool*;
+                                            ^" in self::Extension|get#getter(c) as{TypeError} (core::bool*) →* core::bool*;
 }
diff --git a/pkg/front_end/testcases/general/bug32414a.dart.strong.expect b/pkg/front_end/testcases/general/bug32414a.dart.strong.expect
index ef9dfa5..c83aa71 100644
--- a/pkg/front_end/testcases/general/bug32414a.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bug32414a.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/bug32414a.dart:10:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   b = 42;
 //       ^
 //
@@ -14,7 +13,6 @@
   dynamic a = 5;
   core::String* b = a.{core::Object::toString}();
   b = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/bug32414a.dart:10:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   b = 42;
       ^" in 42 as{TypeError} core::String*;
 }
diff --git a/pkg/front_end/testcases/general/bug32414a.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug32414a.dart.strong.transformed.expect
index ef9dfa5..c83aa71 100644
--- a/pkg/front_end/testcases/general/bug32414a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug32414a.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/bug32414a.dart:10:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   b = 42;
 //       ^
 //
@@ -14,7 +13,6 @@
   dynamic a = 5;
   core::String* b = a.{core::Object::toString}();
   b = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/bug32414a.dart:10:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   b = 42;
       ^" in 42 as{TypeError} core::String*;
 }
diff --git a/pkg/front_end/testcases/general/bug33298.dart.strong.expect b/pkg/front_end/testcases/general/bug33298.dart.strong.expect
index 57e3d95..9f48c8a 100644
--- a/pkg/front_end/testcases/general/bug33298.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bug33298.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
-// Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
 //   List<String> list6 = ['a', 'b', 'c'].map(c).toList();
 //                                            ^
 //
@@ -41,7 +40,6 @@
   self::C* c = new self::C::•();
   core::List<core::String*>* list5 = <core::String*>["a", "b", "c"].{core::Iterable::map}<core::String*>(c.{self::C::call}<core::String*>).{core::Iterable::toList}();
   core::List<core::String*>* list6 = <core::String*>["a", "b", "c"].{core::Iterable::map}<dynamic>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
-Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
   List<String> list6 = ['a', 'b', 'c'].map(c).toList();
                                            ^" in (let final self::C* #t4 = c in #t4.==(null) ?{<T extends core::Object* = dynamic>(T*) →* T*} null : #t4.{self::C::call}) as{TypeError} (core::String*) →* dynamic).{core::Iterable::toList}() as{TypeError} core::List<core::String*>*;
 }
diff --git a/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect
index 57e3d95..9f48c8a 100644
--- a/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
-// Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
 //   List<String> list6 = ['a', 'b', 'c'].map(c).toList();
 //                                            ^
 //
@@ -41,7 +40,6 @@
   self::C* c = new self::C::•();
   core::List<core::String*>* list5 = <core::String*>["a", "b", "c"].{core::Iterable::map}<core::String*>(c.{self::C::call}<core::String*>).{core::Iterable::toList}();
   core::List<core::String*>* list6 = <core::String*>["a", "b", "c"].{core::Iterable::map}<dynamic>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
-Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
   List<String> list6 = ['a', 'b', 'c'].map(c).toList();
                                            ^" in (let final self::C* #t4 = c in #t4.==(null) ?{<T extends core::Object* = dynamic>(T*) →* T*} null : #t4.{self::C::call}) as{TypeError} (core::String*) →* dynamic).{core::Iterable::toList}() as{TypeError} core::List<core::String*>*;
 }
diff --git a/pkg/front_end/testcases/general/cascade.dart.strong.expect b/pkg/front_end/testcases/general/cascade.dart.strong.expect
index b60aced..808b5ca 100644
--- a/pkg/front_end/testcases/general/cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/general/cascade.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     [1]
 //     ^
 //
@@ -35,7 +34,6 @@
   core::print(list);
   list = let final core::List<core::int*>* #t13 = <core::int*>[let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     [1]
     ^" in <core::int*>[1] as{TypeError} core::int*] in let final dynamic #t15 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
diff --git a/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect
index af029ef..a6369df 100644
--- a/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/cascade.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     [1]
 //     ^
 //
@@ -35,7 +34,6 @@
   core::print(list);
   list = let final core::List<core::int*>* #t13 = <core::int*>[let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     [1]
     ^" in <core::int*>[1] as{TypeError} core::int*] in let final core::String* #t15 = invalid-expression "pkg/front_end/testcases/general/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
index c0c603a..c865110 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
@@ -36,32 +36,26 @@
 //                                                    ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) "bar"];
 //                            ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) "bar", null};
 //                            ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
 //                                           ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) ...["bar"]];
 //                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) ...["bar"], null};
 //                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
 //                                               ^
 //
@@ -81,32 +75,26 @@
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                                             ^
 //
@@ -149,57 +137,46 @@
 //                        ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   List<int> list20 = [if (42) 42];
 //                           ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   Set<int> set20 = {if (42) 42};
 //                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   Map<int, int> map30 = {if (42) 42: 42};
 //                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   List<String> list40 = <String>[if (oracle("foo")) true else 42];
 //                                                     ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   List<String> list40 = <String>[if (oracle("foo")) true else 42];
 //                                                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
 //                                                   ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
 //                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
 //                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
 //                                                                           ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
@@ -231,52 +208,42 @@
 //                ^^^^^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
 //                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
 //                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                  ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                                     ^
 //
@@ -296,32 +263,26 @@
 //                                                     ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                                            ^
 //
@@ -371,32 +332,26 @@
 //                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                                      ^
 //
@@ -416,47 +371,38 @@
 //                                    ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                          ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var list60 = [for (; "not bool";) 42];
 //                        ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var set60 = {for (; "not bool";) 42, null};
 //                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var map60 = {for (; "not bool";) "bar": 42, "baz": null};
 //                       ^
 //
@@ -1024,7 +970,6 @@
     final core::List<core::int*>* #t140 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t140.{core::List::add}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[if (oracle(\"foo\")) \"bar\"];
                            ^" in "bar" as{TypeError} core::int*);
   } =>#t140;
@@ -1032,7 +977,6 @@
     final core::Set<core::int*>* #t142 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t142.{core::Set::add}(let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
                            ^" in "bar" as{TypeError} core::int*);
     #t142.{core::Set::add}(null);
@@ -1041,7 +985,6 @@
     final core::Map<core::String*, core::int*>* #t144 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t144.{core::Map::[]=}("bar", let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
                                           ^" in "bar" as{TypeError} core::int*);
     #t144.{core::Map::[]=}("baz", null);
@@ -1050,7 +993,6 @@
     final core::List<core::int*>* #t146 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       for (final core::int* #t147 in <core::int*>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
                                ^" in "bar" as{TypeError} core::int*])
         #t146.{core::List::add}(#t147);
@@ -1059,7 +1001,6 @@
     final core::Set<core::int*>* #t149 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       for (final core::int* #t150 in <core::int*>[let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
                                ^" in "bar" as{TypeError} core::int*])
         #t149.{core::Set::add}(#t150);
@@ -1069,7 +1010,6 @@
     final core::Map<core::String*, core::int*>* #t152 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       for (final core::MapEntry<core::String*, core::int*>* #t153 in <core::String*, core::int*>{"bar": let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
         #t152.{core::Map::[]=}(#t153.{core::MapEntry::key}, #t153.{core::MapEntry::value});
@@ -1103,12 +1043,10 @@
     final core::List<core::String*>* #t157 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t157.{core::List::add}(let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                               ^" in 42 as{TypeError} core::String*);
     else
       #t157.{core::List::add}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                                       ^" in 3.14 as{TypeError} core::String*);
   } =>#t157;
@@ -1116,12 +1054,10 @@
     final core::Set<core::String*>* #t160 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t160.{core::Set::add}(let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                               ^" in 42 as{TypeError} core::String*);
     else
       #t160.{core::Set::add}(let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                                       ^" in 3.14 as{TypeError} core::String*);
     #t160.{core::Set::add}(null);
@@ -1130,12 +1066,10 @@
     final core::Map<core::String*, core::String*>* #t163 = <core::String*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t163.{core::Map::[]=}("bar", let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                              ^" in 42 as{TypeError} core::String*);
     else
       #t163.{core::Map::[]=}("baz", let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                                             ^" in 3.14 as{TypeError} core::String*);
     #t163.{core::Map::[]=}("baz", null);
@@ -1217,7 +1151,6 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t170 = <core::int*>[];
     if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   List<int> list20 = [if (42) 42];
                           ^" in 42 as{TypeError} core::bool*)
       #t170.{core::List::add}(42);
@@ -1225,7 +1158,6 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t172 = col::LinkedHashSet::•<core::int*>();
     if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
       #t172.{core::Set::add}(42);
@@ -1233,7 +1165,6 @@
   core::Map<core::int*, core::int*>* map30 = block {
     final core::Map<core::int*, core::int*>* #t174 = <core::int*, core::int*>{};
     if(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   Map<int, int> map30 = {if (42) 42: 42};
                              ^" in 42 as{TypeError} core::bool*)
       #t174.{core::Map::[]=}(42, 42);
@@ -1242,12 +1173,10 @@
     final core::List<core::String*>* #t176 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t176.{core::List::add}(let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                     ^" in true as{TypeError} core::String*);
     else
       #t176.{core::List::add}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                               ^" in 42 as{TypeError} core::String*);
   } =>#t176;
@@ -1255,12 +1184,10 @@
     final core::Set<core::String*>* #t179 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t179.{core::Set::add}(let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                   ^" in true as{TypeError} core::String*);
     else
       #t179.{core::Set::add}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                             ^" in 42 as{TypeError} core::String*);
   } =>#t179;
@@ -1268,12 +1195,10 @@
     final core::Map<core::String*, core::int*>* #t182 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t182.{core::Map::[]=}(let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                             ^" in true as{TypeError} core::String*, 42);
     else
       #t182.{core::Map::[]=}(let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                                           ^" in 42 as{TypeError} core::String*, 42);
   } =>#t182;
@@ -1281,12 +1206,10 @@
     final core::Map<core::int*, core::String*>* #t185 = <core::int*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t185.{core::Map::[]=}(42, let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                 ^" in true as{TypeError} core::String*);
     else
       #t185.{core::Map::[]=}(42, let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                               ^" in 42 as{TypeError} core::String*);
   } =>#t185;
@@ -1889,7 +1812,6 @@
     final core::List<core::int*>* #t342 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       #t342.{core::List::add}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
                                             ^" in "bar" as{TypeError} core::int*);
   } =>#t342;
@@ -1897,7 +1819,6 @@
     final core::Set<core::int*>* #t344 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       #t344.{core::Set::add}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
                                             ^" in "bar" as{TypeError} core::int*);
     #t344.{core::Set::add}(null);
@@ -1906,14 +1827,11 @@
     final core::Map<core::int*, core::int*>* #t346 = <core::int*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       #t346.{core::Map::[]=}(let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                  ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                         ^" in "bar" as{TypeError} core::int*);
     #t346.{core::Map::[]=}(let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                                ^" in "baz" as{TypeError} core::int*, null);
   } =>#t346;
@@ -1921,7 +1839,6 @@
     final core::List<core::int*>* #t350 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       for (final core::int* #t351 in <core::int*>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
                                                 ^" in "bar" as{TypeError} core::int*])
         #t350.{core::List::add}(#t351);
@@ -1930,7 +1847,6 @@
     final core::Set<core::int*>* #t353 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       for (final core::int* #t354 in <core::int*>[let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
                                                 ^" in "bar" as{TypeError} core::int*])
         #t353.{core::Set::add}(#t354);
@@ -1940,15 +1856,12 @@
     final core::Map<core::int*, core::int*>* #t356 = <core::int*, core::int*>{};
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       for (final core::MapEntry<core::int*, core::int*>* #t357 in <core::int*, core::int*>{let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                      ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
         #t356.{core::Map::[]=}(#t357.{core::MapEntry::key}, #t357.{core::MapEntry::value});
     #t356.{core::Map::[]=}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int*, null);
   } =>#t356;
@@ -1981,12 +1894,10 @@
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError} core::bool*)
         #t363.{core::List::add}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                              ^" in 42 as{TypeError} core::String*);
       else
         #t363.{core::List::add}(let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                                      ^" in 3.14 as{TypeError} core::String*);
   } =>#t363;
@@ -1995,12 +1906,10 @@
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError} core::bool*)
         #t366.{core::Set::add}(let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                              ^" in 42 as{TypeError} core::String*);
       else
         #t366.{core::Set::add}(let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                                      ^" in 3.14 as{TypeError} core::String*);
     #t366.{core::Set::add}(null);
@@ -2010,12 +1919,10 @@
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
       if(self::oracle<dynamic>() as{TypeError} core::bool*)
         #t369.{core::Map::[]=}("bar", let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                             ^" in 42 as{TypeError} core::String*);
       else
         #t369.{core::Map::[]=}("bar", let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                                            ^" in 3.14 as{TypeError} core::String*);
     #t369.{core::Map::[]=}("baz", null);
@@ -2139,10 +2046,8 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t388 = <core::int*>[];
     for (core::int* i in <core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                ^" in "not" as{TypeError} core::int*, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int*])
       #t388.{core::List::add}(i);
@@ -2150,10 +2055,8 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t391 = col::LinkedHashSet::•<core::int*>();
     for (core::int* i in <core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int*])
       #t391.{core::Set::add}(i);
@@ -2162,10 +2065,8 @@
   core::Map<core::String*, core::int*>* map20 = block {
     final core::Map<core::String*, core::int*>* #t394 = <core::String*, core::int*>{};
     for (core::int* i in <core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int*])
       #t394.{core::Map::[]=}("bar", i);
@@ -2200,10 +2101,8 @@
   core::List<core::int*>* list40 = block {
     final core::List<core::int*>* #t403 = <core::int*>[];
     await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                          ^" in "not" as{TypeError} core::int*, let final<BottomType> #t405 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int*]))
       #t403.{core::List::add}(i);
@@ -2211,10 +2110,8 @@
   core::Set<core::int*>* set40 = block {
     final core::Set<core::int*>* #t406 = col::LinkedHashSet::•<core::int*>();
     await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t407 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int*]))
       #t406.{core::Set::add}(i);
@@ -2223,10 +2120,8 @@
   core::Map<core::String*, core::int*>* map40 = block {
     final core::Map<core::String*, core::int*>* #t409 = <core::String*, core::int*>{};
     await for (core::int* i in asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t410 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t411 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int*]))
       #t409.{core::Map::[]=}("bar", i);
@@ -2252,7 +2147,6 @@
   core::List<core::int*>* list60 = block {
     final core::List<core::int*>* #t415 = <core::int*>[];
     for (; let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool*; )
       #t415.{core::List::add}(42);
@@ -2260,7 +2154,6 @@
   core::Set<core::int*>* set60 = block {
     final core::Set<core::int*>* #t417 = col::LinkedHashSet::•<core::int*>();
     for (; let final<BottomType> #t418 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
       #t417.{core::Set::add}(42);
@@ -2269,7 +2162,6 @@
   core::Map<core::String*, core::int*>* map60 = block {
     final core::Map<core::String*, core::int*>* #t419 = <core::String*, core::int*>{};
     for (; let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool*; )
       #t419.{core::Map::[]=}("bar", 42);
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index 27878cb..4360cc9 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -36,32 +36,26 @@
 //                                                    ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) "bar"];
 //                            ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) "bar", null};
 //                            ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
 //                                           ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) ...["bar"]];
 //                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) ...["bar"], null};
 //                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
 //                                               ^
 //
@@ -81,32 +75,26 @@
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                                             ^
 //
@@ -149,57 +137,46 @@
 //                        ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   List<int> list20 = [if (42) 42];
 //                           ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   Set<int> set20 = {if (42) 42};
 //                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   Map<int, int> map30 = {if (42) 42: 42};
 //                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   List<String> list40 = <String>[if (oracle("foo")) true else 42];
 //                                                     ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   List<String> list40 = <String>[if (oracle("foo")) true else 42];
 //                                                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
 //                                                   ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
 //                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
 //                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
 //                                                                           ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
@@ -231,52 +208,42 @@
 //                ^^^^^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
 //                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
 //                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                  ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                                     ^
 //
@@ -296,32 +263,26 @@
 //                                                     ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                             ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                                            ^
 //
@@ -371,32 +332,26 @@
 //                              ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                                      ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                               ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                                      ^
 //
@@ -416,47 +371,38 @@
 //                                    ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                          ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                                 ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                         ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                                ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var list60 = [for (; "not bool";) 42];
 //                        ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var set60 = {for (; "not bool";) 42, null};
 //                       ^
 //
 // pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var map60 = {for (; "not bool";) "bar": 42, "baz": null};
 //                       ^
 //
@@ -1024,7 +970,6 @@
     final core::List<core::int*>* #t140 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t140.{core::List::add}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[if (oracle(\"foo\")) \"bar\"];
                            ^" in "bar" as{TypeError} core::int*);
   } =>#t140;
@@ -1032,7 +977,6 @@
     final core::Set<core::int*>* #t142 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t142.{core::Set::add}(let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{if (oracle(\"foo\")) \"bar\", null};
                            ^" in "bar" as{TypeError} core::int*);
     #t142.{core::Set::add}(null);
@@ -1041,7 +985,6 @@
     final core::Map<core::String*, core::int*>* #t144 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t144.{core::Map::[]=}("bar", let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
                                           ^" in "bar" as{TypeError} core::int*);
     #t144.{core::Map::[]=}("baz", null);
@@ -1050,7 +993,6 @@
     final core::List<core::int*>* #t146 = <core::int*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       for (final core::int* #t147 in <core::int*>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
                                ^" in "bar" as{TypeError} core::int*])
         #t146.{core::List::add}(#t147);
@@ -1059,7 +1001,6 @@
     final core::Set<core::int*>* #t149 = col::LinkedHashSet::•<core::int*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       for (final core::int* #t150 in <core::int*>[let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
                                ^" in "bar" as{TypeError} core::int*])
         #t149.{core::Set::add}(#t150);
@@ -1069,7 +1010,6 @@
     final core::Map<core::String*, core::int*>* #t152 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       for (final core::MapEntry<core::String*, core::int*>* #t153 in <core::String*, core::int*>{"bar": let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
         #t152.{core::Map::[]=}(#t153.{core::MapEntry::key}, #t153.{core::MapEntry::value});
@@ -1103,12 +1043,10 @@
     final core::List<core::String*>* #t157 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t157.{core::List::add}(let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                               ^" in 42 as{TypeError} core::String*);
     else
       #t157.{core::List::add}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
                                       ^" in 3.14 as{TypeError} core::String*);
   } =>#t157;
@@ -1116,12 +1054,10 @@
     final core::Set<core::String*>* #t160 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t160.{core::Set::add}(let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                               ^" in 42 as{TypeError} core::String*);
     else
       #t160.{core::Set::add}(let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
                                       ^" in 3.14 as{TypeError} core::String*);
     #t160.{core::Set::add}(null);
@@ -1130,12 +1066,10 @@
     final core::Map<core::String*, core::String*>* #t163 = <core::String*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t163.{core::Map::[]=}("bar", let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                              ^" in 42 as{TypeError} core::String*);
     else
       #t163.{core::Map::[]=}("baz", let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
                                                             ^" in 3.14 as{TypeError} core::String*);
     #t163.{core::Map::[]=}("baz", null);
@@ -1217,7 +1151,6 @@
   core::List<core::int*>* list20 = block {
     final core::List<core::int*>* #t170 = <core::int*>[];
     if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   List<int> list20 = [if (42) 42];
                           ^" in 42 as{TypeError} core::bool*)
       #t170.{core::List::add}(42);
@@ -1225,7 +1158,6 @@
   core::Set<core::int*>* set20 = block {
     final core::Set<core::int*>* #t172 = col::LinkedHashSet::•<core::int*>();
     if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   Set<int> set20 = {if (42) 42};
                         ^" in 42 as{TypeError} core::bool*)
       #t172.{core::Set::add}(42);
@@ -1233,7 +1165,6 @@
   core::Map<core::int*, core::int*>* map30 = block {
     final core::Map<core::int*, core::int*>* #t174 = <core::int*, core::int*>{};
     if(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   Map<int, int> map30 = {if (42) 42: 42};
                              ^" in 42 as{TypeError} core::bool*)
       #t174.{core::Map::[]=}(42, 42);
@@ -1242,12 +1173,10 @@
     final core::List<core::String*>* #t176 = <core::String*>[];
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t176.{core::List::add}(let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                     ^" in true as{TypeError} core::String*);
     else
       #t176.{core::List::add}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
                                                               ^" in 42 as{TypeError} core::String*);
   } =>#t176;
@@ -1255,12 +1184,10 @@
     final core::Set<core::String*>* #t179 = col::LinkedHashSet::•<core::String*>();
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t179.{core::Set::add}(let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                   ^" in true as{TypeError} core::String*);
     else
       #t179.{core::Set::add}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
                                                             ^" in 42 as{TypeError} core::String*);
   } =>#t179;
@@ -1268,12 +1195,10 @@
     final core::Map<core::String*, core::int*>* #t182 = <core::String*, core::int*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t182.{core::Map::[]=}(let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                             ^" in true as{TypeError} core::String*, 42);
     else
       #t182.{core::Map::[]=}(let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
                                                                           ^" in 42 as{TypeError} core::String*, 42);
   } =>#t182;
@@ -1281,12 +1206,10 @@
     final core::Map<core::int*, core::String*>* #t185 = <core::int*, core::String*>{};
     if(self::oracle<core::String*>("foo") as{TypeError} core::bool*)
       #t185.{core::Map::[]=}(42, let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                 ^" in true as{TypeError} core::String*);
     else
       #t185.{core::Map::[]=}(42, let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
                                                                               ^" in 42 as{TypeError} core::String*);
   } =>#t185;
@@ -1904,7 +1827,6 @@
           final core::List<core::int*>* #t342 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             #t342.{core::List::add}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
                                             ^" in "bar" as{TypeError} core::int*);
         } =>#t342;
@@ -1912,7 +1834,6 @@
           final core::Set<core::int*>* #t344 = col::LinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             #t344.{core::Set::add}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
                                             ^" in "bar" as{TypeError} core::int*);
           #t344.{core::Set::add}(null);
@@ -1921,14 +1842,11 @@
           final core::Map<core::int*, core::int*>* #t346 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             #t346.{core::Map::[]=}(let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                  ^" in "bar" as{TypeError} core::int*, let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                         ^" in "bar" as{TypeError} core::int*);
           #t346.{core::Map::[]=}(let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
                                                                ^" in "baz" as{TypeError} core::int*, null);
         } =>#t346;
@@ -1936,7 +1854,6 @@
           final core::List<core::int*>* #t350 = <core::int*>[];
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             for (final core::int* #t351 in <core::int*>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
                                                 ^" in "bar" as{TypeError} core::int*])
               #t350.{core::List::add}(#t351);
@@ -1945,7 +1862,6 @@
           final core::Set<core::int*>* #t353 = col::LinkedHashSet::•<core::int*>();
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             for (final core::int* #t354 in <core::int*>[let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
                                                 ^" in "bar" as{TypeError} core::int*])
               #t353.{core::Set::add}(#t354);
@@ -1955,15 +1871,12 @@
           final core::Map<core::int*, core::int*>* #t356 = <core::int*, core::int*>{};
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             for (final core::MapEntry<core::int*, core::int*>* #t357 in <core::int*, core::int*>{let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                      ^" in "bar" as{TypeError} core::int*: let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int*}.{core::Map::entries})
               #t356.{core::Map::[]=}(#t357.{core::MapEntry::key}, #t357.{core::MapEntry::value});
           #t356.{core::Map::[]=}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int*, null);
         } =>#t356;
@@ -1996,12 +1909,10 @@
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError} core::bool*)
               #t363.{core::List::add}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                              ^" in 42 as{TypeError} core::String*);
             else
               #t363.{core::List::add}(let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
                                                                      ^" in 3.14 as{TypeError} core::String*);
         } =>#t363;
@@ -2010,12 +1921,10 @@
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError} core::bool*)
               #t366.{core::Set::add}(let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                              ^" in 42 as{TypeError} core::String*);
             else
               #t366.{core::Set::add}(let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
                                                                      ^" in 3.14 as{TypeError} core::String*);
           #t366.{core::Set::add}(null);
@@ -2025,12 +1934,10 @@
           for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError} core::bool*; i = i.{core::num::+}(1))
             if(self::oracle<dynamic>() as{TypeError} core::bool*)
               #t369.{core::Map::[]=}("bar", let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                             ^" in 42 as{TypeError} core::String*);
             else
               #t369.{core::Map::[]=}("bar", let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
                                                                                            ^" in 3.14 as{TypeError} core::String*);
           #t369.{core::Map::[]=}("baz", null);
@@ -2154,10 +2061,8 @@
         core::List<core::int*>* list20 = block {
           final core::List<core::int*>* #t388 = <core::int*>[];
           for (core::int* i in <core::int*>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                ^" in "not" as{TypeError} core::int*, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int*])
             #t388.{core::List::add}(i);
@@ -2165,10 +2070,8 @@
         core::Set<core::int*>* set20 = block {
           final core::Set<core::int*>* #t391 = col::LinkedHashSet::•<core::int*>();
           for (core::int* i in <core::int*>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int*])
             #t391.{core::Set::add}(i);
@@ -2177,10 +2080,8 @@
         core::Map<core::String*, core::int*>* map20 = block {
           final core::Map<core::String*, core::int*>* #t394 = <core::String*, core::int*>{};
           for (core::int* i in <core::int*>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                               ^" in "not" as{TypeError} core::int*, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int*])
             #t394.{core::Map::[]=}("bar", i);
@@ -2274,10 +2175,8 @@
         final core::List<core::int*>* #t412 = <core::int*>[];
         {
           dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                          ^" in "not" as{TypeError} core::int*, let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int*]);
           asy::_asyncStarListenHelper(:stream, :async_op);
@@ -2304,10 +2203,8 @@
         final core::Set<core::int*>* #t418 = col::LinkedHashSet::•<core::int*>();
         {
           dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int*]);
           asy::_asyncStarListenHelper(:stream, :async_op);
@@ -2336,10 +2233,8 @@
         final core::Map<core::String*, core::int*>* #t424 = <core::String*, core::int*>{};
         {
           dynamic :stream = asy::Stream::fromIterable<core::int*>(<core::int*>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                         ^" in "not" as{TypeError} core::int*, let final<BottomType> #t426 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int*]);
           asy::_asyncStarListenHelper(:stream, :async_op);
@@ -2385,7 +2280,6 @@
         core::List<core::int*>* list60 = block {
           final core::List<core::int*>* #t433 = <core::int*>[];
           for (; let final<BottomType> #t434 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool*; )
             #t433.{core::List::add}(42);
@@ -2393,7 +2287,6 @@
         core::Set<core::int*>* set60 = block {
           final core::Set<core::int*>* #t435 = col::LinkedHashSet::•<core::int*>();
           for (; let final<BottomType> #t436 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool*; )
             #t435.{core::Set::add}(42);
@@ -2402,7 +2295,6 @@
         core::Map<core::String*, core::int*>* map60 = block {
           final core::Map<core::String*, core::int*>* #t437 = <core::String*, core::int*>{};
           for (; let final<BottomType> #t438 = invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
-Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool*; )
             #t437.{core::Map::[]=}("bar", 42);
diff --git a/pkg/front_end/testcases/general/function_type_assignments.dart.strong.expect b/pkg/front_end/testcases/general/function_type_assignments.dart.strong.expect
index 4c4931a..ab5443b 100644
--- a/pkg/front_end/testcases/general/function_type_assignments.dart.strong.expect
+++ b/pkg/front_end/testcases/general/function_type_assignments.dart.strong.expect
@@ -3,19 +3,16 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String x = identity; // No bound
 //            ^
 //
 // pkg/front_end/testcases/general/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
 //  - 'Object' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String y = identityObject; // Object bound
 //            ^
 //
 // pkg/front_end/testcases/general/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String z = identityList; // List<T> bound
 //            ^
 //
@@ -23,17 +20,14 @@
 import "dart:core" as core;
 
 static field core::String* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
 String x = identity; // No bound
            ^" in (#C1) as{TypeError} core::String*;
 static field core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
  - 'Object' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
 String y = identityObject; // Object bound
            ^" in (#C2) as{TypeError} core::String*;
 static field core::String* z = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
 String z = identityList; // List<T> bound
            ^" in (#C3) as{TypeError} core::String*;
 static method identity<T extends core::Object* = dynamic>(self::identity::T* t) → self::identity::T*
diff --git a/pkg/front_end/testcases/general/function_type_assignments.dart.strong.transformed.expect b/pkg/front_end/testcases/general/function_type_assignments.dart.strong.transformed.expect
index 4c4931a..ab5443b 100644
--- a/pkg/front_end/testcases/general/function_type_assignments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/function_type_assignments.dart.strong.transformed.expect
@@ -3,19 +3,16 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String x = identity; // No bound
 //            ^
 //
 // pkg/front_end/testcases/general/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
 //  - 'Object' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String y = identityObject; // Object bound
 //            ^
 //
 // pkg/front_end/testcases/general/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String z = identityList; // List<T> bound
 //            ^
 //
@@ -23,17 +20,14 @@
 import "dart:core" as core;
 
 static field core::String* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
 String x = identity; // No bound
            ^" in (#C1) as{TypeError} core::String*;
 static field core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
  - 'Object' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
 String y = identityObject; // Object bound
            ^" in (#C2) as{TypeError} core::String*;
 static field core::String* z = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
 String z = identityList; // List<T> bound
            ^" in (#C3) as{TypeError} core::String*;
 static method identity<T extends core::Object* = dynamic>(self::identity::T* t) → self::identity::T*
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart b/pkg/front_end/testcases/general/generic_function_type_in_message.dart
new file mode 100644
index 0000000..e4eaf36
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+num add<A extends num, B extends num>(A a, B b) => a + b;
+
+test() {
+  int x = add;
+}
+
+main() {
+  if (add(1,2) < 3) test();
+}
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.outline.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.outline.expect
new file mode 100644
index 0000000..c236efd
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method add<A extends core::num* = core::num*, B extends core::num* = core::num*>(self::add::A* a, self::add::B* b) → core::num*
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.strong.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.strong.expect
new file mode 100644
index 0000000..e9469d1
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.strong.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/generic_function_type_in_message.dart:8:11: Error: A value of type 'num Function<A extends num, B extends num>(A, B)' can't be assigned to a variable of type 'int'.
+//   int x = add;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method add<A extends core::num* = core::num*, B extends core::num* = core::num*>(self::add::A* a, self::add::B* b) → core::num*
+  return a.{core::num::+}(b);
+static method test() → dynamic {
+  core::int* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/generic_function_type_in_message.dart:8:11: Error: A value of type 'num Function<A extends num, B extends num>(A, B)' can't be assigned to a variable of type 'int'.
+  int x = add;
+          ^" in (#C1) as{TypeError} core::int*;
+}
+static method main() → dynamic {
+  if(self::add<core::int*, core::int*>(1, 2).{core::num::<}(3))
+    self::test();
+}
+
+constants  {
+  #C1 = tearoff self::add
+}
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.strong.transformed.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.strong.transformed.expect
new file mode 100644
index 0000000..e9469d1
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/generic_function_type_in_message.dart:8:11: Error: A value of type 'num Function<A extends num, B extends num>(A, B)' can't be assigned to a variable of type 'int'.
+//   int x = add;
+//           ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method add<A extends core::num* = core::num*, B extends core::num* = core::num*>(self::add::A* a, self::add::B* b) → core::num*
+  return a.{core::num::+}(b);
+static method test() → dynamic {
+  core::int* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/generic_function_type_in_message.dart:8:11: Error: A value of type 'num Function<A extends num, B extends num>(A, B)' can't be assigned to a variable of type 'int'.
+  int x = add;
+          ^" in (#C1) as{TypeError} core::int*;
+}
+static method main() → dynamic {
+  if(self::add<core::int*, core::int*>(1, 2).{core::num::<}(3))
+    self::test();
+}
+
+constants  {
+  #C1 = tearoff self::add
+}
diff --git a/pkg/front_end/testcases/general/invalid_assignment.dart.strong.expect b/pkg/front_end/testcases/general/invalid_assignment.dart.strong.expect
index 0085ccf..b5ac381 100644
--- a/pkg/front_end/testcases/general/invalid_assignment.dart.strong.expect
+++ b/pkg/front_end/testcases/general/invalid_assignment.dart.strong.expect
@@ -3,18 +3,15 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/invalid_assignment.dart:11:7: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i = s;
 //       ^
 //
 // pkg/front_end/testcases/general/invalid_assignment.dart:13:9: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i ??= s;
 //         ^
 //
 // pkg/front_end/testcases/general/invalid_assignment.dart:15:5: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/general/invalid_assignment.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   a += 1;
 //     ^
 //
@@ -31,18 +28,15 @@
 static method test(core::int* i, core::String* s, self::A* a) → dynamic {
   i = 1;
   i = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/invalid_assignment.dart:11:7: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   i = s;
       ^" in s as{TypeError} core::int*;
   i.{core::num::==}(null) ?{core::int*} i = 1 : null;
   i.{core::num::==}(null) ?{core::Object*} i = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/invalid_assignment.dart:13:9: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   i ??= s;
         ^" in s as{TypeError} core::int* : null;
   a = new self::A::•();
   a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/invalid_assignment.dart:15:5: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/general/invalid_assignment.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
   a += 1;
     ^" in a.{self::A::+}(1) as{TypeError} self::A*;
 }
diff --git a/pkg/front_end/testcases/general/invalid_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/general/invalid_assignment.dart.strong.transformed.expect
index 0085ccf..b5ac381 100644
--- a/pkg/front_end/testcases/general/invalid_assignment.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/invalid_assignment.dart.strong.transformed.expect
@@ -3,18 +3,15 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/invalid_assignment.dart:11:7: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i = s;
 //       ^
 //
 // pkg/front_end/testcases/general/invalid_assignment.dart:13:9: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i ??= s;
 //         ^
 //
 // pkg/front_end/testcases/general/invalid_assignment.dart:15:5: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/general/invalid_assignment.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   a += 1;
 //     ^
 //
@@ -31,18 +28,15 @@
 static method test(core::int* i, core::String* s, self::A* a) → dynamic {
   i = 1;
   i = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/invalid_assignment.dart:11:7: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   i = s;
       ^" in s as{TypeError} core::int*;
   i.{core::num::==}(null) ?{core::int*} i = 1 : null;
   i.{core::num::==}(null) ?{core::Object*} i = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/invalid_assignment.dart:13:9: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   i ??= s;
         ^" in s as{TypeError} core::int* : null;
   a = new self::A::•();
   a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/invalid_assignment.dart:15:5: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/general/invalid_assignment.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
   a += 1;
     ^" in a.{self::A::+}(1) as{TypeError} self::A*;
 }
diff --git a/pkg/front_end/testcases/general/optional.dart.strong.expect b/pkg/front_end/testcases/general/optional.dart.strong.expect
index 42a1431..6c29683 100644
--- a/pkg/front_end/testcases/general/optional.dart.strong.expect
+++ b/pkg/front_end/testcases/general/optional.dart.strong.expect
@@ -5,7 +5,6 @@
 // pkg/front_end/testcases/general/optional.dart:47:21: Error: The argument type 'InvalidListener' can't be assigned to the parameter type 'Listener'.
 //  - 'InvalidListener' is from 'pkg/front_end/testcases/general/optional.dart'.
 //  - 'Listener' is from 'pkg/front_end/testcases/general/optional.dart'.
-// Try changing the type of the parameter, or casting the argument to 'Listener'.
 //   extern.listen(new InvalidListener());
 //                     ^
 //
@@ -84,7 +83,6 @@
   extern.{self::External::listen}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/optional.dart:47:21: Error: The argument type 'InvalidListener' can't be assigned to the parameter type 'Listener'.
  - 'InvalidListener' is from 'pkg/front_end/testcases/general/optional.dart'.
  - 'Listener' is from 'pkg/front_end/testcases/general/optional.dart'.
-Try changing the type of the parameter, or casting the argument to 'Listener'.
   extern.listen(new InvalidListener());
                     ^" in new self::InvalidListener::•() as{TypeError} self::Listener*);
   dynamic nothing1 = foo.{self::Foo::method}();
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.expect
index 14038f4..1a27647 100644
--- a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.expect
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'T'.
-// Try changing the type of the parameter, or casting the argument to 'T'.
 //   Foo.from(String _init) : this._internal(x: _init);
 //                                              ^
 //
@@ -14,7 +13,6 @@
   generic-covariant-impl field self::Foo::T* x;
   constructor from(core::String* _init) → self::Foo<self::Foo::T*>*
     : this self::Foo::_internal(x: let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'T'.
-Try changing the type of the parameter, or casting the argument to 'T'.
   Foo.from(String _init) : this._internal(x: _init);
                                              ^" in _init as{TypeError} <BottomType>)
     ;
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.transformed.expect
index 14038f4..1a27647 100644
--- a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'T'.
-// Try changing the type of the parameter, or casting the argument to 'T'.
 //   Foo.from(String _init) : this._internal(x: _init);
 //                                              ^
 //
@@ -14,7 +13,6 @@
   generic-covariant-impl field self::Foo::T* x;
   constructor from(core::String* _init) → self::Foo<self::Foo::T*>*
     : this self::Foo::_internal(x: let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'T'.
-Try changing the type of the parameter, or casting the argument to 'T'.
   Foo.from(String _init) : this._internal(x: _init);
                                              ^" in _init as{TypeError} <BottomType>)
     ;
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect
index 0013246..c5e1b01 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.expect
@@ -13,31 +13,26 @@
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int lhs30 = /*@ typeArgs=int* */ [...spread];
 //                                    ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
 //  - 'Set' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int set30 = /*@ typeArgs=int* */ {...spread, 42};
 //                                    ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
 //  - 'Set' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       {...spread};
 //       ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       {...mapSpread, "baz": 42};
 //       ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       {...mapSpread};
 //       ^
 //
@@ -235,7 +230,6 @@
                            ^";
   core::int* lhs30 = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   int lhs30 = /*@ typeArgs=int* */ [...spread];
                                    ^" in ( block {
     final core::List<core::int*>* #t45 = <core::int*>[];
@@ -244,7 +238,6 @@
   } =>#t45) as{TypeError} core::int*;
   core::int* set30 = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   int set30 = /*@ typeArgs=int* */ {...spread, 42};
                                    ^" in ( block {
     final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
@@ -254,7 +247,6 @@
   } =>#t48) as{TypeError} core::int*;
   core::int* set30ambiguous = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       {...spread};
       ^" in ( block {
     final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
@@ -265,7 +257,6 @@
   } =>#t51) as{TypeError} core::int*;
   core::int* map30 = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       {...mapSpread, \"baz\": 42};
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
@@ -275,7 +266,6 @@
   } =>#t55) as{TypeError} core::int*;
   core::int* map30ambiguous = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       {...mapSpread};
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
index 00963f1..3a6b58b 100644
--- a/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.strong.transformed.expect
@@ -13,31 +13,26 @@
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int lhs30 = /*@ typeArgs=int* */ [...spread];
 //                                    ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
 //  - 'Set' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int set30 = /*@ typeArgs=int* */ {...spread, 42};
 //                                    ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
 //  - 'Set' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       {...spread};
 //       ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       {...mapSpread, "baz": 42};
 //       ^
 //
 // pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       {...mapSpread};
 //       ^
 //
@@ -235,7 +230,6 @@
                            ^";
   core::int* lhs30 = let final<BottomType> #t44 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:98:36: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   int lhs30 = /*@ typeArgs=int* */ [...spread];
                                    ^" in ( block {
     final core::List<core::int*>* #t45 = <core::int*>[];
@@ -244,7 +238,6 @@
   } =>#t45) as{TypeError} core::int*;
   core::int* set30 = let final<BottomType> #t47 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:100:36: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   int set30 = /*@ typeArgs=int* */ {...spread, 42};
                                    ^" in ( block {
     final core::Set<core::int*>* #t48 = col::LinkedHashSet::•<core::int*>();
@@ -254,7 +247,6 @@
   } =>#t48) as{TypeError} core::int*;
   core::int* set30ambiguous = let final<BottomType> #t50 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:103:7: Error: A value of type 'Set<int>' can't be assigned to a variable of type 'int'.
  - 'Set' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       {...spread};
       ^" in ( block {
     final core::Set<core::int*>* #t51 = col::LinkedHashSet::•<core::int*>();
@@ -265,7 +257,6 @@
   } =>#t51) as{TypeError} core::int*;
   core::int* map30 = let final<BottomType> #t54 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:106:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       {...mapSpread, \"baz\": 42};
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t55 = <core::String*, core::int*>{};
@@ -275,7 +266,6 @@
   } =>#t55) as{TypeError} core::int*;
   core::int* map30ambiguous = let final<BottomType> #t57 = invalid-expression "pkg/front_end/testcases/general/spread_collection_inference.dart:109:7: Error: A value of type 'Map<String, int>' can't be assigned to a variable of type 'int'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       {...mapSpread};
       ^" in ( block {
     final core::Map<core::String*, core::int*>* #t58 = <core::String*, core::int*>{};
diff --git a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.expect b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.expect
index b0d2afa..ee44e8f 100644
--- a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.expect
+++ b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.expect
@@ -6,7 +6,6 @@
 //  - 'List' is from 'dart:core'.
 //  - 'int/*1*/' is from 'pkg/front_end/testcases/general/type_parameter_type_named_int.dart'.
 //  - 'int/*2*/' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<int/*2*/>'.
 //     list = value;
 //            ^
 //
@@ -30,7 +29,6 @@
  - 'List' is from 'dart:core'.
  - 'int/*1*/' is from 'pkg/front_end/testcases/general/type_parameter_type_named_int.dart'.
  - 'int/*2*/' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<int/*2*/>'.
     list = value;
            ^" in value as{TypeError} core::List<core::int*>*;
   }
diff --git a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.transformed.expect
index b0d2afa..ee44e8f 100644
--- a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.strong.transformed.expect
@@ -6,7 +6,6 @@
 //  - 'List' is from 'dart:core'.
 //  - 'int/*1*/' is from 'pkg/front_end/testcases/general/type_parameter_type_named_int.dart'.
 //  - 'int/*2*/' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<int/*2*/>'.
 //     list = value;
 //            ^
 //
@@ -30,7 +29,6 @@
  - 'List' is from 'dart:core'.
  - 'int/*1*/' is from 'pkg/front_end/testcases/general/type_parameter_type_named_int.dart'.
  - 'int/*2*/' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<int/*2*/>'.
     list = value;
            ^" in value as{TypeError} core::List<core::int*>*;
   }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect
index 45ab27e..8d7d832 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     return /*error:RETURN_OF_INVALID_TYPE*/ 1;
 //                                             ^
 //
@@ -16,7 +15,6 @@
   () →* core::String* g = f;
   g = () → core::String* {
     return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     return /*error:RETURN_OF_INVALID_TYPE*/ 1;
                                             ^" in 1 as{TypeError} core::String*;
   };
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
index 45ab27e..8d7d832 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     return /*error:RETURN_OF_INVALID_TYPE*/ 1;
 //                                             ^
 //
@@ -16,7 +15,6 @@
   () →* core::String* g = f;
   g = () → core::String* {
     return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     return /*error:RETURN_OF_INVALID_TYPE*/ 1;
                                             ^" in 1 as{TypeError} core::String*;
   };
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
index d506668..f8657ce 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
 //                                                        ^
 //
@@ -24,7 +23,6 @@
   self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in let final dynamic #t2 = #t1.{self::C::t} = 1.0 in #t1;
   self::C<dynamic>* c_dynamic = new self::C::•<dynamic>(42);
   x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
                                                        ^" in "hello" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
index 095e6b5..3bc4490 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
 //                                                        ^
 //
@@ -24,7 +23,6 @@
   self::C<core::num*>* c_num2 = let final self::C<core::num*>* #t1 = new self::C::•<core::num*>(456) in let final core::double* #t2 = #t1.{self::C::t} = 1.0 in #t1;
   self::C<dynamic>* c_dynamic = new self::C::•<dynamic>(42);
   x.{self::C::t} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
                                                        ^" in "hello" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
index d2d97ba..860cc4e 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
 //                                                        ^
 //
@@ -24,7 +23,6 @@
 static method test() → dynamic {
   self::C<core::int*>* x = self::C::•<core::int*>(42);
   x.{self::C::t} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
                                                        ^" in "hello" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
index d2d97ba..860cc4e 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
 //                                                        ^
 //
@@ -24,7 +23,6 @@
 static method test() → dynamic {
   self::C<core::int*>* x = self::C::•<core::int*>(42);
   x.{self::C::t} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
                                                        ^" in "hello" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect
index 70d558d..a30551f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   l = /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"];
 //                                                                        ^
 //
@@ -13,7 +12,6 @@
 static method test() → void {
   core::List<core::int*>* l;
   l = <core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   l = /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"];
                                                                        ^" in "hello" as{TypeError} core::int*];
   l = l = <core::int*>[1];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
index 70d558d..a30551f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   l = /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"];
 //                                                                        ^
 //
@@ -13,7 +12,6 @@
 static method test() → void {
   core::List<core::int*>* l;
   l = <core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   l = /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"];
                                                                        ^" in "hello" as{TypeError} core::int*];
   l = l = <core::int*>[1];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect
index 362c6b2..fb74527 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect
@@ -3,52 +3,42 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
@@ -79,51 +69,41 @@
   new self::F0::•(<core::int*>[]);
   new self::F0::•(<core::int*>[3]);
   new self::F0::•(<core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F0::•(<core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F1::•(a: <core::int*>[]);
   new self::F1::•(a: <core::int*>[3]);
   new self::F1::•(a: <core::int*>[let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                ^" in "hello" as{TypeError} core::int*]);
   new self::F1::•(a: <core::int*>[let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F2::•(<core::int*>[]);
   new self::F2::•(<core::int*>[3]);
   new self::F2::•(<core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F2::•(<core::int*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F3::•(<core::Iterable<core::int*>*>[]);
   new self::F3::•(<core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F3::•(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F3::•(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
index 362c6b2..fb74527 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
@@ -3,52 +3,42 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
@@ -79,51 +69,41 @@
   new self::F0::•(<core::int*>[]);
   new self::F0::•(<core::int*>[3]);
   new self::F0::•(<core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F0::•(<core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F1::•(a: <core::int*>[]);
   new self::F1::•(a: <core::int*>[3]);
   new self::F1::•(a: <core::int*>[let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                ^" in "hello" as{TypeError} core::int*]);
   new self::F1::•(a: <core::int*>[let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F2::•(<core::int*>[]);
   new self::F2::•(<core::int*>[3]);
   new self::F2::•(<core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F2::•(<core::int*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F3::•(<core::Iterable<core::int*>*>[]);
   new self::F3::•(<core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F3::•(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F3::•(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F4::•(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect
index 25b17e9..50c0c51 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect
@@ -3,52 +3,42 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:17:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello", 3]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:21:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f1(a: /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                          ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:23:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:29:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:30:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello", 3]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:37:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:40:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:49:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:52:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
@@ -64,51 +54,41 @@
   self::f0(<core::int*>[]);
   self::f0(<core::int*>[3]);
   self::f0(<core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                       ^" in "hello" as{TypeError} core::int*]);
   self::f0(<core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:17:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\", 3]);
                                                                       ^" in "hello" as{TypeError} core::int*, 3]);
   self::f1(a: <core::int*>[]);
   self::f1(a: <core::int*>[3]);
   self::f1(a: <core::int*>[let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:21:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f1(a: /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                          ^" in "hello" as{TypeError} core::int*]);
   self::f1(a: <core::int*>[let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:23:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   self::f2(<core::int*>[]);
   self::f2(<core::int*>[3]);
   self::f2(<core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:29:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                       ^" in "hello" as{TypeError} core::int*]);
   self::f2(<core::int*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:30:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\", 3]);
                                                                       ^" in "hello" as{TypeError} core::int*, 3]);
   self::f3(<core::Iterable<core::int*>*>[]);
   self::f3(<core::Iterable<core::int*>*>[<core::int*>[3]]);
   self::f3(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:37:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   self::f3(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:40:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   self::f4(a: <core::Iterable<core::int*>*>[]);
   self::f4(a: <core::Iterable<core::int*>*>[<core::int*>[3]]);
   self::f4(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:49:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   self::f4(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:52:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
index 25b17e9..50c0c51 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
@@ -3,52 +3,42 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:17:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello", 3]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:21:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f1(a: /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                          ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:23:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:29:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:30:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello", 3]);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:37:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:40:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:49:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:52:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
@@ -64,51 +54,41 @@
   self::f0(<core::int*>[]);
   self::f0(<core::int*>[3]);
   self::f0(<core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                       ^" in "hello" as{TypeError} core::int*]);
   self::f0(<core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:17:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f0(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\", 3]);
                                                                       ^" in "hello" as{TypeError} core::int*, 3]);
   self::f1(a: <core::int*>[]);
   self::f1(a: <core::int*>[3]);
   self::f1(a: <core::int*>[let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:21:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f1(a: /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                          ^" in "hello" as{TypeError} core::int*]);
   self::f1(a: <core::int*>[let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:23:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   self::f2(<core::int*>[]);
   self::f2(<core::int*>[3]);
   self::f2(<core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:29:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                       ^" in "hello" as{TypeError} core::int*]);
   self::f2(<core::int*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:30:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f2(/*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\", 3]);
                                                                       ^" in "hello" as{TypeError} core::int*, 3]);
   self::f3(<core::Iterable<core::int*>*>[]);
   self::f3(<core::Iterable<core::int*>*>[<core::int*>[3]]);
   self::f3(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:37:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   self::f3(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:40:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   self::f4(a: <core::Iterable<core::int*>*>[]);
   self::f4(a: <core::Iterable<core::int*>*>[<core::int*>[3]]);
   self::f4(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:49:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   self::f4(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:52:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
index e7f54af..e52fb83 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
@@ -3,53 +3,43 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:69: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
 //         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (String x) =>
 //                                                                     ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:18:80: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         l3 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (int x) => 3;
 //                                                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:20:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //             3;
 //             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:31:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:34:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ x;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:76: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function(int)'.
 //         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=List<String*>* */ (String
 //                                                                            ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:46:58: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //               /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                          ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                    ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:60:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //             x;
 //             ^
 //
@@ -67,16 +57,13 @@
     (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
     (core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
     (core::int*) →* core::String* l2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:69: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (String x) =>
                                                                     ^" in ((core::String* x) → core::String* => "hello") as{TypeError} (core::int*) →* core::String*;
     (core::int*) →* core::String* l3 = (core::int* x) → core::String* => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:18:80: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         l3 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (int x) => 3;
                                                                                ^" in 3 as{TypeError} core::String*;
     (core::int*) →* core::String* l4 = (core::int* x) → core::String* {
       return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:20:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
@@ -85,18 +72,15 @@
     (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
     (core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
     (core::int*) →* core::String* l2 = (core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
             3;
             ^" in 3 as{TypeError} core::String*;
     (core::int*) →* core::String* l3 = (core::int* x) → core::String* {
       return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:31:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
     (core::int*) →* core::String* l4 = (core::int* x) → core::String* {
       return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:34:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ x;
                                               ^" in x as{TypeError} core::String*;
     };
@@ -106,16 +90,13 @@
     (core::int*) →* core::List<core::String*>* l1 = (core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
     (core::int*) →* core::List<core::String*>* l2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:76: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function(int)'.
         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=List<String*>* */ (String
                                                                            ^" in ((core::String* x) → core::List<core::String*>* => <core::String*>["hello"]) as{TypeError} (core::int*) →* core::List<core::String*>*;
     (core::int*) →* core::List<core::String*>* l3 = (core::int* x) → core::List<core::String*>* => <core::String*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:46:58: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
               /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                          ^" in 3 as{TypeError} core::String*];
     (core::int*) →* core::List<core::String*>* l4 = (core::int* x) → core::List<core::String*>* {
       return <core::String*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                    ^" in 3 as{TypeError} core::String*];
     };
@@ -124,7 +105,6 @@
     (core::int*) →* core::int* l0 = (core::int* x) → core::int* => x;
     (core::int*) →* core::int* l1 = (core::int* x) → core::int* => x.{core::num::+}(1);
     (core::int*) →* core::String* l2 = (core::int* x) → core::String* => let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:60:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
             x;
             ^" in x as{TypeError} core::String*;
     (core::int*) →* core::String* l3 = (core::int* x) → core::String* => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
index e7f54af..e52fb83 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
@@ -3,53 +3,43 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:69: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
 //         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (String x) =>
 //                                                                     ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:18:80: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         l3 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (int x) => 3;
 //                                                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:20:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //             3;
 //             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:31:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:34:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ x;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:76: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function(int)'.
 //         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=List<String*>* */ (String
 //                                                                            ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:46:58: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //               /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                          ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                    ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:60:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //             x;
 //             ^
 //
@@ -67,16 +57,13 @@
     (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
     (core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
     (core::int*) →* core::String* l2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:69: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (String x) =>
                                                                     ^" in ((core::String* x) → core::String* => "hello") as{TypeError} (core::int*) →* core::String*;
     (core::int*) →* core::String* l3 = (core::int* x) → core::String* => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:18:80: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         l3 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (int x) => 3;
                                                                                ^" in 3 as{TypeError} core::String*;
     (core::int*) →* core::String* l4 = (core::int* x) → core::String* {
       return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:20:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
@@ -85,18 +72,15 @@
     (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
     (core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
     (core::int*) →* core::String* l2 = (core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
             3;
             ^" in 3 as{TypeError} core::String*;
     (core::int*) →* core::String* l3 = (core::int* x) → core::String* {
       return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:31:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
     (core::int*) →* core::String* l4 = (core::int* x) → core::String* {
       return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:34:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ x;
                                               ^" in x as{TypeError} core::String*;
     };
@@ -106,16 +90,13 @@
     (core::int*) →* core::List<core::String*>* l1 = (core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
     (core::int*) →* core::List<core::String*>* l2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:76: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function(int)'.
         l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=List<String*>* */ (String
                                                                            ^" in ((core::String* x) → core::List<core::String*>* => <core::String*>["hello"]) as{TypeError} (core::int*) →* core::List<core::String*>*;
     (core::int*) →* core::List<core::String*>* l3 = (core::int* x) → core::List<core::String*>* => <core::String*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:46:58: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
               /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                          ^" in 3 as{TypeError} core::String*];
     (core::int*) →* core::List<core::String*>* l4 = (core::int* x) → core::List<core::String*>* {
       return <core::String*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                    ^" in 3 as{TypeError} core::String*];
     };
@@ -124,7 +105,6 @@
     (core::int*) →* core::int* l0 = (core::int* x) → core::int* => x;
     (core::int*) →* core::int* l1 = (core::int* x) → core::int* => x.{core::num::+}(1);
     (core::int*) →* core::String* l2 = (core::int* x) → core::String* => let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:60:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
             x;
             ^" in x as{TypeError} core::String*;
     (core::int*) →* core::String* l3 = (core::int* x) → core::String* => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect
index df3f4ac..c46c3b5 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect
@@ -3,52 +3,42 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
@@ -79,51 +69,41 @@
   new self::F0::•<core::int*>(<core::int*>[]);
   new self::F0::•<core::int*>(<core::int*>[3]);
   new self::F0::•<core::int*>(<core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F0::•<core::int*>(<core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F1::•<core::int*>(a: <core::int*>[]);
   new self::F1::•<core::int*>(a: <core::int*>[3]);
   new self::F1::•<core::int*>(a: <core::int*>[let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                ^" in "hello" as{TypeError} core::int*]);
   new self::F1::•<core::int*>(a: <core::int*>[let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F2::•<core::int*>(<core::int*>[]);
   new self::F2::•<core::int*>(<core::int*>[3]);
   new self::F2::•<core::int*>(<core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F2::•<core::int*>(<core::int*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   new self::F3::•<dynamic>(<core::Iterable<dynamic>*>[]);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
index df3f4ac..c46c3b5 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
@@ -3,52 +3,42 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                      ^
 //
@@ -79,51 +69,41 @@
   new self::F0::•<core::int*>(<core::int*>[]);
   new self::F0::•<core::int*>(<core::int*>[3]);
   new self::F0::•<core::int*>(<core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F0::•<core::int*>(<core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F1::•<core::int*>(a: <core::int*>[]);
   new self::F1::•<core::int*>(a: <core::int*>[3]);
   new self::F1::•<core::int*>(a: <core::int*>[let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                ^" in "hello" as{TypeError} core::int*]);
   new self::F1::•<core::int*>(a: <core::int*>[let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F2::•<core::int*>(<core::int*>[]);
   new self::F2::•<core::int*>(<core::int*>[3]);
   new self::F2::•<core::int*>(<core::int*>[let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:51:72: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
                                                                        ^" in "hello" as{TypeError} core::int*]);
   new self::F2::•<core::int*>(<core::int*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, 3]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:62:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F3::•<core::int*>(<core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:65:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[<core::int*>[3]]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:74:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
                                                                      ^" in "hello" as{TypeError} core::int*]]);
   new self::F4::•<core::int*>(a: <core::Iterable<core::int*>*>[<core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:77:70: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     /*@ typeArgs=int* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
                                                                      ^" in "hello" as{TypeError} core::int*], <core::int*>[3]]);
   new self::F3::•<dynamic>(<core::Iterable<dynamic>*>[]);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
index 3adb8ba..40d578f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
@@ -3,53 +3,43 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:68: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
 //     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (String x) =>
 //                                                                    ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:16:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (int x) => 3;
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:18:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         3;
 //         ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:30:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:33:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ x;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:75: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function<S>(int)'.
 //     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=List<String*>* */ (String
 //                                                                           ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:46:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                    ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:64:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         x;
 //         ^
 //
@@ -69,16 +59,13 @@
     v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
     v = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:68: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (String x) =>
                                                                    ^" in (<T extends core::Object* = dynamic>(core::String* x) → core::String* => "hello") as{TypeError} <S extends core::Object* = dynamic>(core::int*) →* core::String*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:16:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (int x) => 3;
                                                                               ^" in 3 as{TypeError} core::String*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* {
       return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:18:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
@@ -90,18 +77,15 @@
     v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         3;
         ^" in 3 as{TypeError} core::String*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* {
       return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:30:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* {
       return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:33:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ x;
                                               ^" in x as{TypeError} core::String*;
     };
@@ -114,16 +98,13 @@
     v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
     v = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:75: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function<S>(int)'.
     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=List<String*>* */ (String
                                                                           ^" in (<T extends core::Object* = dynamic>(core::String* x) → core::List<core::String*>* => <core::String*>["hello"]) as{TypeError} <S extends core::Object* = dynamic>(core::int*) →* core::List<core::String*>*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* => <core::String*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:46:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                      ^" in 3 as{TypeError} core::String*];
     v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* {
       return <core::String*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                    ^" in 3 as{TypeError} core::String*];
     };
@@ -140,7 +121,6 @@
     x = <T extends core::Object* = dynamic>(core::int* x) → core::int* => x.{core::num::+}(1);
     <T extends core::Object* = dynamic>(core::int*) →* core::String* y = int2String;
     y = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:64:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         x;
         ^" in x as{TypeError} core::String*;
     y = <T extends core::Object* = dynamic>(core::int* x) → core::String* => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
index 3adb8ba..40d578f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
@@ -3,53 +3,43 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:68: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
 //     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (String x) =>
 //                                                                    ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:16:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (int x) => 3;
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:18:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         3;
 //         ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:30:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:33:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       return /*error:RETURN_OF_INVALID_TYPE*/ x;
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:75: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function<S>(int)'.
 //     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=List<String*>* */ (String
 //                                                                           ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:46:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                    ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:64:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //         x;
 //         ^
 //
@@ -69,16 +59,13 @@
     v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
     v = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:68: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (String x) =>
                                                                    ^" in (<T extends core::Object* = dynamic>(core::String* x) → core::String* => "hello") as{TypeError} <S extends core::Object* = dynamic>(core::int*) →* core::String*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:16:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (int x) => 3;
                                                                               ^" in 3 as{TypeError} core::String*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* {
       return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:18:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
@@ -90,18 +77,15 @@
     v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         3;
         ^" in 3 as{TypeError} core::String*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* {
       return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:30:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
                                               ^" in 3 as{TypeError} core::String*;
     };
     v = <T extends core::Object* = dynamic>(core::int* x) → core::String* {
       return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:33:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       return /*error:RETURN_OF_INVALID_TYPE*/ x;
                                               ^" in x as{TypeError} core::String*;
     };
@@ -114,16 +98,13 @@
     v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
     v = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:75: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function<S>(int)'.
     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=List<String*>* */ (String
                                                                           ^" in (<T extends core::Object* = dynamic>(core::String* x) → core::List<core::String*>* => <core::String*>["hello"]) as{TypeError} <S extends core::Object* = dynamic>(core::int*) →* core::List<core::String*>*;
     v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* => <core::String*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:46:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                      ^" in 3 as{TypeError} core::String*];
     v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* {
       return <core::String*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                    ^" in 3 as{TypeError} core::String*];
     };
@@ -140,7 +121,6 @@
     x = <T extends core::Object* = dynamic>(core::int* x) → core::int* => x.{core::num::+}(1);
     <T extends core::Object* = dynamic>(core::int*) →* core::String* y = int2String;
     y = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:64:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
         x;
         ^" in x as{TypeError} core::String*;
     y = <T extends core::Object* = dynamic>(core::int* x) → core::String* => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
index 35c8e0e..7a22f09 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
@@ -15,129 +15,106 @@
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:53:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:54:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:56:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:57:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:65:47: Error: A value of type 'B<String, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a4 = /*error:INVALID_ASSIGNMENT*/ new B<String, dynamic>("hello", 3);
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:67:47: Error: A value of type 'B<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a5 = /*error:INVALID_ASSIGNMENT*/ new B<dynamic, dynamic>.named(
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:72:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:73:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:75:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:76:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:83:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
 //  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
 //     A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>(3);
 //                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:84:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
 //  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
 //     A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>.named(3);
 //                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:88:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:90:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:98:47: Error: A value of type 'D<num, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a4 = /*error:INVALID_ASSIGNMENT*/ new D<num, dynamic>("hello");
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:100:47: Error: A value of type 'D<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a5 = /*error:INVALID_ASSIGNMENT*/ new D<dynamic, dynamic>.named(
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:105:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:107:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:118:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:121:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:129:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:130:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:134:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
@@ -210,17 +187,13 @@
   }
   {
     self::A<core::int*, core::String*>* a0 = new self::A::•<core::int*, core::String*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:53:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:54:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
     self::A<core::int*, core::String*>* a1 = new self::A::named<core::int*, core::String*>(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:56:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:57:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
   }
@@ -232,29 +205,23 @@
     self::A<core::int*, core::String*>* a4 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:65:47: Error: A value of type 'B<String, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a4 = /*error:INVALID_ASSIGNMENT*/ new B<String, dynamic>(\"hello\", 3);
                                               ^" in new self::B::•<core::String*, dynamic>("hello", 3) as{TypeError} self::A<core::int*, core::String*>*;
     self::A<core::int*, core::String*>* a5 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:67:47: Error: A value of type 'B<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a5 = /*error:INVALID_ASSIGNMENT*/ new B<dynamic, dynamic>.named(
                                               ^" in new self::B::named<dynamic, dynamic>("hello", 3) as{TypeError} self::A<core::int*, core::String*>*;
   }
   {
     self::A<core::int*, core::String*>* a0 = new self::B::•<core::String*, core::int*>(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:72:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
                                                ^" in 3 as{TypeError} core::String*, let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:73:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
     self::A<core::int*, core::String*>* a1 = new self::B::named<core::String*, core::int*>(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:75:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
                                                ^" in 3 as{TypeError} core::String*, let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:76:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
   }
@@ -266,23 +233,19 @@
     self::A<core::int*, core::int*>* a4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:83:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
     A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>(3);
                                                       ^" in new self::C::•<dynamic>(3) as{TypeError} self::A<core::int*, core::int*>*;
     self::A<core::int*, core::int*>* a5 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:84:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
     A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>.named(3);
                                                       ^" in new self::C::named<dynamic>(3) as{TypeError} self::A<core::int*, core::int*>*;
   }
   {
     self::A<core::int*, core::int*>* a0 = new self::C::•<core::int*>(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:88:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
     self::A<core::int*, core::int*>* a1 = new self::C::named<core::int*>(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:90:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
   }
@@ -294,23 +257,19 @@
     self::A<core::int*, core::String*>* a4 = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:98:47: Error: A value of type 'D<num, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a4 = /*error:INVALID_ASSIGNMENT*/ new D<num, dynamic>(\"hello\");
                                               ^" in new self::D::•<core::num*, dynamic>("hello") as{TypeError} self::A<core::int*, core::String*>*;
     self::A<core::int*, core::String*>* a5 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:100:47: Error: A value of type 'D<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a5 = /*error:INVALID_ASSIGNMENT*/ new D<dynamic, dynamic>.named(
                                               ^" in new self::D::named<dynamic, dynamic>("hello") as{TypeError} self::A<core::int*, core::String*>*;
   }
   {
     self::A<core::int*, core::String*>* a0 = new self::D::•<dynamic, core::String*>(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:105:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
     self::A<core::int*, core::String*>* a1 = new self::D::named<dynamic, core::String*>(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:107:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
   }
@@ -320,23 +279,18 @@
   {
     self::A<core::int*, core::String*>* a0 = new self::F::•<core::int*, core::String*>(3, "hello", a: <core::int*>[3], b: <core::String*>["hello"]);
     self::A<core::int*, core::String*>* a1 = new self::F::•<core::int*, core::String*>(3, "hello", a: <core::int*>[let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:118:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                      ^" in "hello" as{TypeError} core::int*], b: <core::String*>[let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:121:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                      ^" in 3 as{TypeError} core::String*]);
     self::A<core::int*, core::String*>* a2 = new self::F::named<core::int*, core::String*>(3, "hello", 3, "hello");
     self::A<core::int*, core::String*>* a3 = new self::F::named<core::int*, core::String*>(3, "hello");
     self::A<core::int*, core::String*>* a4 = new self::F::named<core::int*, core::String*>(3, "hello", let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:129:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:130:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
     self::A<core::int*, core::String*>* a5 = new self::F::named<core::int*, core::String*>(3, "hello", let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:134:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
index 35c8e0e..7a22f09 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
@@ -15,129 +15,106 @@
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:53:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:54:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:56:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:57:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:65:47: Error: A value of type 'B<String, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a4 = /*error:INVALID_ASSIGNMENT*/ new B<String, dynamic>("hello", 3);
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:67:47: Error: A value of type 'B<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a5 = /*error:INVALID_ASSIGNMENT*/ new B<dynamic, dynamic>.named(
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:72:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:73:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:75:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:76:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:83:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
 //  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
 //     A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>(3);
 //                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:84:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
 //  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
 //     A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>.named(3);
 //                                                       ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:88:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:90:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:98:47: Error: A value of type 'D<num, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a4 = /*error:INVALID_ASSIGNMENT*/ new D<num, dynamic>("hello");
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:100:47: Error: A value of type 'D<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
 //  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
 //         a5 = /*error:INVALID_ASSIGNMENT*/ new D<dynamic, dynamic>.named(
 //                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:105:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:107:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:118:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:121:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:129:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:130:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
 //                                                ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:134:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
 //
@@ -210,17 +187,13 @@
   }
   {
     self::A<core::int*, core::String*>* a0 = new self::A::•<core::int*, core::String*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:53:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:54:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
     self::A<core::int*, core::String*>* a1 = new self::A::named<core::int*, core::String*>(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:56:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:57:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
   }
@@ -232,29 +205,23 @@
     self::A<core::int*, core::String*>* a4 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:65:47: Error: A value of type 'B<String, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a4 = /*error:INVALID_ASSIGNMENT*/ new B<String, dynamic>(\"hello\", 3);
                                               ^" in new self::B::•<core::String*, dynamic>("hello", 3) as{TypeError} self::A<core::int*, core::String*>*;
     self::A<core::int*, core::String*>* a5 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:67:47: Error: A value of type 'B<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a5 = /*error:INVALID_ASSIGNMENT*/ new B<dynamic, dynamic>.named(
                                               ^" in new self::B::named<dynamic, dynamic>("hello", 3) as{TypeError} self::A<core::int*, core::String*>*;
   }
   {
     self::A<core::int*, core::String*>* a0 = new self::B::•<core::String*, core::int*>(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:72:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
                                                ^" in 3 as{TypeError} core::String*, let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:73:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
     self::A<core::int*, core::String*>* a1 = new self::B::named<core::String*, core::int*>(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:75:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
                                                ^" in 3 as{TypeError} core::String*, let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:76:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
   }
@@ -266,23 +233,19 @@
     self::A<core::int*, core::int*>* a4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:83:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
     A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>(3);
                                                       ^" in new self::C::•<dynamic>(3) as{TypeError} self::A<core::int*, core::int*>*;
     self::A<core::int*, core::int*>* a5 = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:84:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
     A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>.named(3);
                                                       ^" in new self::C::named<dynamic>(3) as{TypeError} self::A<core::int*, core::int*>*;
   }
   {
     self::A<core::int*, core::int*>* a0 = new self::C::•<core::int*>(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:88:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
     self::A<core::int*, core::int*>* a1 = new self::C::named<core::int*>(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:90:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
   }
@@ -294,23 +257,19 @@
     self::A<core::int*, core::String*>* a4 = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:98:47: Error: A value of type 'D<num, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a4 = /*error:INVALID_ASSIGNMENT*/ new D<num, dynamic>(\"hello\");
                                               ^" in new self::D::•<core::num*, dynamic>("hello") as{TypeError} self::A<core::int*, core::String*>*;
     self::A<core::int*, core::String*>* a5 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:100:47: Error: A value of type 'D<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
         a5 = /*error:INVALID_ASSIGNMENT*/ new D<dynamic, dynamic>.named(
                                               ^" in new self::D::named<dynamic, dynamic>("hello") as{TypeError} self::A<core::int*, core::String*>*;
   }
   {
     self::A<core::int*, core::String*>* a0 = new self::D::•<dynamic, core::String*>(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:105:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
     self::A<core::int*, core::String*>* a1 = new self::D::named<dynamic, core::String*>(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:107:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
   }
@@ -320,23 +279,18 @@
   {
     self::A<core::int*, core::String*>* a0 = new self::F::•<core::int*, core::String*>(3, "hello", a: <core::int*>[3], b: <core::String*>["hello"]);
     self::A<core::int*, core::String*>* a1 = new self::F::•<core::int*, core::String*>(3, "hello", a: <core::int*>[let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:118:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                      ^" in "hello" as{TypeError} core::int*], b: <core::String*>[let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:121:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
                                                      ^" in 3 as{TypeError} core::String*]);
     self::A<core::int*, core::String*>* a2 = new self::F::named<core::int*, core::String*>(3, "hello", 3, "hello");
     self::A<core::int*, core::String*>* a3 = new self::F::named<core::int*, core::String*>(3, "hello");
     self::A<core::int*, core::String*>* a4 = new self::F::named<core::int*, core::String*>(3, "hello", let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:129:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                ^" in "hello" as{TypeError} core::int*, let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:130:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
                                                ^" in 3 as{TypeError} core::String*);
     self::A<core::int*, core::String*>* a5 = new self::F::named<core::int*, core::String*>(3, "hello", let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:134:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
                                                ^" in "hello" as{TypeError} core::int*);
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect
index 6f0f9ee..fc86f60 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42
 //                                                                                         ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:19:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:22:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                  ^
 //
@@ -30,7 +27,6 @@
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:36:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                  ^
 //
@@ -41,7 +37,6 @@
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:39:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                  ^
 //
@@ -52,22 +47,18 @@
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:47:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:50:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:58:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                                                         ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:61:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                                                         ^
 //
@@ -75,7 +66,6 @@
 import "dart:core" as core;
 
 static method foo([core::List<core::String*>* list1 = #C1, core::List<core::String*>* list2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42
                                                                                         ^"]) → void {}
 static method main() → void {
@@ -83,11 +73,9 @@
     core::List<core::int*>* l0 = <core::int*>[];
     core::List<core::int*>* l1 = <core::int*>[3];
     core::List<core::int*>* l2 = <core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:19:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                  ^" in "hello" as{TypeError} core::int*];
     core::List<core::int*>* l3 = <core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:22:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                  ^" in "hello" as{TypeError} core::int*, 3];
   }
@@ -113,7 +101,6 @@
 Change the type of the list literal or the context in which it is used.
     List<int> l2 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
                                                             ^" in <core::num*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:36:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                  ^" in "hello" as{TypeError} core::num*];
     core::List<core::int*>* l3 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:38:61: Error: The list literal type 'List<num>' isn't of expected type 'List<int>'.
@@ -121,7 +108,6 @@
 Change the type of the list literal or the context in which it is used.
     List<int> l3 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
                                                             ^" in <core::num*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:39:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                  ^" in "hello" as{TypeError} core::num*, 3];
   }
@@ -129,21 +115,17 @@
     core::Iterable<core::int*>* i0 = <core::int*>[];
     core::Iterable<core::int*>* i1 = <core::int*>[3];
     core::Iterable<core::int*>* i2 = <core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:47:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                  ^" in "hello" as{TypeError} core::int*];
     core::Iterable<core::int*>* i3 = <core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:50:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                  ^" in "hello" as{TypeError} core::int*, 3];
   }
   {
     const core::List<core::int*>* c2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:58:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                                                         ^";
     const core::List<core::int*>* c3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:61:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                                                         ^";
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
index 6f0f9ee..fc86f60 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42
 //                                                                                         ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:19:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:22:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                  ^
 //
@@ -30,7 +27,6 @@
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:36:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                  ^
 //
@@ -41,7 +37,6 @@
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:39:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                  ^
 //
@@ -52,22 +47,18 @@
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:47:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:50:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:58:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
 //                                                                                         ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:61:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                                                         ^
 //
@@ -75,7 +66,6 @@
 import "dart:core" as core;
 
 static method foo([core::List<core::String*>* list1 = #C1, core::List<core::String*>* list2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42
                                                                                         ^"]) → void {}
 static method main() → void {
@@ -83,11 +73,9 @@
     core::List<core::int*>* l0 = <core::int*>[];
     core::List<core::int*>* l1 = <core::int*>[3];
     core::List<core::int*>* l2 = <core::int*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:19:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                  ^" in "hello" as{TypeError} core::int*];
     core::List<core::int*>* l3 = <core::int*>[let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:22:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                  ^" in "hello" as{TypeError} core::int*, 3];
   }
@@ -113,7 +101,6 @@
 Change the type of the list literal or the context in which it is used.
     List<int> l2 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
                                                             ^" in <core::num*>[let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:36:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                  ^" in "hello" as{TypeError} core::num*];
     core::List<core::int*>* l3 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:38:61: Error: The list literal type 'List<num>' isn't of expected type 'List<int>'.
@@ -121,7 +108,6 @@
 Change the type of the list literal or the context in which it is used.
     List<int> l3 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
                                                             ^" in <core::num*>[let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:39:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                  ^" in "hello" as{TypeError} core::num*, 3];
   }
@@ -129,21 +115,17 @@
     core::Iterable<core::int*>* i0 = <core::int*>[];
     core::Iterable<core::int*>* i1 = <core::int*>[3];
     core::Iterable<core::int*>* i2 = <core::int*>[let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:47:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                  ^" in "hello" as{TypeError} core::int*];
     core::Iterable<core::int*>* i3 = <core::int*>[let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:50:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                  ^" in "hello" as{TypeError} core::int*, 3];
   }
   {
     const core::List<core::int*>* c2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:58:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
                                                                                         ^";
     const core::List<core::int*>* c3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:61:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
                                                                                         ^";
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect
index a4d1d04..82a617d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect
@@ -3,47 +3,38 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:20:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": "hello"
 //                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:23:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:27:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:28:51: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                   ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:48:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:52:56: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       "hello": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:59:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": "hello"
 //                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:64:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": 3
 //                                             ^
 //
@@ -66,22 +57,18 @@
 //                                                                            ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:80:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:84:86: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:88:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:89:87: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                                                       ^
 //
@@ -89,7 +76,6 @@
 import "dart:core" as core;
 
 static method foo([core::Map<core::int*, core::String*>* m1 = #C4, core::Map<core::int*, core::String*>* m2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                                                               ^"]) → void {}
 static method test() → void {
@@ -97,18 +83,14 @@
     core::Map<core::int*, core::String*>* l0 = <core::int*, core::String*>{};
     core::Map<core::int*, core::String*>* l1 = <core::int*, core::String*>{3: "hello"};
     core::Map<core::int*, core::String*>* l2 = <core::int*, core::String*>{let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:20:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": \"hello\"
                                             ^" in "hello" as{TypeError} core::int*: "hello"};
     core::Map<core::int*, core::String*>* l3 = <core::int*, core::String*>{3: let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:23:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                  ^" in 3 as{TypeError} core::String*};
     core::Map<core::int*, core::String*>* l4 = <core::int*, core::String*>{3: "hello", let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:27:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                             ^" in "hello" as{TypeError} core::int*: let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:28:51: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                   ^" in 3 as{TypeError} core::String*};
   }
@@ -124,11 +106,9 @@
     core::Map<dynamic, core::String*>* l1 = <dynamic, core::String*>{3: "hello"};
     core::Map<dynamic, core::String*>* l2 = <dynamic, core::String*>{"hello": "hello"};
     core::Map<dynamic, core::String*>* l3 = <dynamic, core::String*>{3: let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:48:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                  ^" in 3 as{TypeError} core::String*};
     core::Map<dynamic, core::String*>* l4 = <dynamic, core::String*>{3: "hello", "hello": let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:52:56: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       \"hello\": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                        ^" in 3 as{TypeError} core::String*};
   }
@@ -136,12 +116,10 @@
     core::Map<core::int*, dynamic>* l0 = <core::int*, dynamic>{};
     core::Map<core::int*, dynamic>* l1 = <core::int*, dynamic>{3: "hello"};
     core::Map<core::int*, dynamic>* l2 = <core::int*, dynamic>{let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:59:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": \"hello\"
                                             ^" in "hello" as{TypeError} core::int*: "hello"};
     core::Map<core::int*, dynamic>* l3 = <core::int*, dynamic>{3: 3};
     core::Map<core::int*, dynamic>* l4 = <core::int*, dynamic>{3: "hello", let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:64:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": 3
                                             ^" in "hello" as{TypeError} core::int*: 3};
   }
@@ -164,15 +142,12 @@
   }
   {
     const core::Map<core::int*, core::String*>* l2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:80:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                                                               ^";
     const core::Map<core::int*, core::String*>* l3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:84:86: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                                                      ^";
     const core::Map<core::int*, core::String*>* l4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:88:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                                                               ^";
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
index a4d1d04..82a617d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
@@ -3,47 +3,38 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:20:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": "hello"
 //                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:23:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:27:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:28:51: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                   ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:48:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                  ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:52:56: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       "hello": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                        ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:59:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": "hello"
 //                                             ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:64:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": 3
 //                                             ^
 //
@@ -66,22 +57,18 @@
 //                                                                            ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:80:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:84:86: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:88:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:89:87: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                                                       ^
 //
@@ -89,7 +76,6 @@
 import "dart:core" as core;
 
 static method foo([core::Map<core::int*, core::String*>* m1 = #C4, core::Map<core::int*, core::String*>* m2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                                                               ^"]) → void {}
 static method test() → void {
@@ -97,18 +83,14 @@
     core::Map<core::int*, core::String*>* l0 = <core::int*, core::String*>{};
     core::Map<core::int*, core::String*>* l1 = <core::int*, core::String*>{3: "hello"};
     core::Map<core::int*, core::String*>* l2 = <core::int*, core::String*>{let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:20:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": \"hello\"
                                             ^" in "hello" as{TypeError} core::int*: "hello"};
     core::Map<core::int*, core::String*>* l3 = <core::int*, core::String*>{3: let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:23:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                  ^" in 3 as{TypeError} core::String*};
     core::Map<core::int*, core::String*>* l4 = <core::int*, core::String*>{3: "hello", let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:27:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                             ^" in "hello" as{TypeError} core::int*: let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:28:51: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                   ^" in 3 as{TypeError} core::String*};
   }
@@ -124,11 +106,9 @@
     core::Map<dynamic, core::String*>* l1 = <dynamic, core::String*>{3: "hello"};
     core::Map<dynamic, core::String*>* l2 = <dynamic, core::String*>{"hello": "hello"};
     core::Map<dynamic, core::String*>* l3 = <dynamic, core::String*>{3: let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:48:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                  ^" in 3 as{TypeError} core::String*};
     core::Map<dynamic, core::String*>* l4 = <dynamic, core::String*>{3: "hello", "hello": let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:52:56: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       \"hello\": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                        ^" in 3 as{TypeError} core::String*};
   }
@@ -136,12 +116,10 @@
     core::Map<core::int*, dynamic>* l0 = <core::int*, dynamic>{};
     core::Map<core::int*, dynamic>* l1 = <core::int*, dynamic>{3: "hello"};
     core::Map<core::int*, dynamic>* l2 = <core::int*, dynamic>{let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:59:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": \"hello\"
                                             ^" in "hello" as{TypeError} core::int*: "hello"};
     core::Map<core::int*, dynamic>* l3 = <core::int*, dynamic>{3: 3};
     core::Map<core::int*, dynamic>* l4 = <core::int*, dynamic>{3: "hello", let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:64:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": 3
                                             ^" in "hello" as{TypeError} core::int*: 3};
   }
@@ -164,15 +142,12 @@
   }
   {
     const core::Map<core::int*, core::String*>* l2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:80:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                                                               ^";
     const core::Map<core::int*, core::String*>* l3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:84:86: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
                                                                                      ^";
     const core::Map<core::int*, core::String*>* l4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:88:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
                                                                               ^";
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
index b3a5d51..a07fb00 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
@@ -5,28 +5,24 @@
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:69: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
 //  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<int>'.
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
 //                                                                     ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Stream' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Stream<List<int>>'.
 //   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Map<int, int>'.
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
 //                                                                     ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
 //  - 'Map' is from 'dart:core'.
 //  - 'Iterable' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Iterable<Map<int, int>>'.
 //   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
 //                                                                               ^
 //
@@ -45,13 +41,11 @@
   yield let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:69: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<int>'.
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
                                                                     ^" in self::MyStream::•<dynamic>() as{TypeError} core::List<core::int*>*;
   yield* let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'Stream<List<int>>'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
                                                                      ^" in core::List::•<dynamic>() as{TypeError} asy::Stream<core::List<core::int*>*>*;
   yield* self::MyStream::•<core::List<core::int*>*>();
@@ -61,13 +55,11 @@
   yield let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
  - 'List' is from 'dart:core'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Map<int, int>'.
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
                                                                     ^" in core::List::•<dynamic>() as{TypeError} core::Map<core::int*, core::int*>*;
   yield* let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
  - 'Map' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Iterable<Map<int, int>>'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
                                                                               ^" in core::Map::•<dynamic, dynamic>() as{TypeError} core::Iterable<core::Map<core::int*, core::int*>*>*;
   yield* core::List::•<core::Map<core::int*, core::int*>*>();
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
index 295f142..0f46239 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
@@ -5,28 +5,24 @@
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:69: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
 //  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<int>'.
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
 //                                                                     ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Stream' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Stream<List<int>>'.
 //   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
 //                                                                      ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
 //  - 'List' is from 'dart:core'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Map<int, int>'.
 //   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
 //                                                                     ^
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
 //  - 'Map' is from 'dart:core'.
 //  - 'Iterable' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Iterable<Map<int, int>>'.
 //   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
 //                                                                               ^
 //
@@ -62,7 +58,6 @@
           if(:controller.{asy::_AsyncStarStreamController::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:69: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<int>'.
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ MyStream();
                                                                     ^" in self::MyStream::•<dynamic>() as{TypeError} core::List<core::int*>*))
             return null;
@@ -71,7 +66,6 @@
           if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:70: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
  - 'List' is from 'dart:core'.
  - 'Stream' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'Stream<List<int>>'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
                                                                      ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} asy::Stream<core::List<core::int*>*>*))
             return null;
@@ -110,7 +104,6 @@
         :iterator.{core::_SyncIterator::_current} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:69: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
  - 'List' is from 'dart:core'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Map<int, int>'.
   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic */ List();
                                                                     ^" in core::_GrowableList::•<dynamic>(0) as{TypeError} core::Map<core::int*, core::int*>*;
         [yield] true;
@@ -119,7 +112,6 @@
         :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:79: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
  - 'Map' is from 'dart:core'.
  - 'Iterable' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Iterable<Map<int, int>>'.
   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@ typeArgs=dynamic, dynamic */ Map();
                                                                               ^" in core::Map::•<dynamic, dynamic>() as{TypeError} core::Iterable<core::Map<core::int*, core::int*>*>*;
         [yield] true;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
index e0b1bf3..3865a9a 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
@@ -5,7 +5,6 @@
 // pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'Future<int>'.
 //  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards.dart'.
 //  - 'Future' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
 //   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                 ^
 //
@@ -38,7 +37,6 @@
   asy::Future<core::int*>* f2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'Future<int>'.
  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards.dart'.
  - 'Future' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
                                                 ^" in f as{TypeError} asy::Future<core::int*>*;
   asy::Future<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3) as asy::Future<core::double*>*;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
index e0b1bf3..3865a9a 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
@@ -5,7 +5,6 @@
 // pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'Future<int>'.
 //  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards.dart'.
 //  - 'Future' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
 //   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                 ^
 //
@@ -38,7 +37,6 @@
   asy::Future<core::int*>* f2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'Future<int>'.
  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards.dart'.
  - 'Future' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
                                                 ^" in f as{TypeError} asy::Future<core::int*>*;
   asy::Future<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3) as asy::Future<core::double*>*;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
index a92b944..ebacc67 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'MyFuture<int>'.
 //  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'MyFuture<int>'.
 //   MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                   ^
 //
@@ -36,7 +35,6 @@
   self::MyFuture<core::double*>* f = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3);
   self::MyFuture<core::int*>* f2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'MyFuture<int>'.
  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'MyFuture<int>'.
   MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
                                                   ^" in f as{TypeError} self::MyFuture<core::int*>*;
   self::MyFuture<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3) as self::MyFuture<core::double*>*;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
index a92b944..ebacc67 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'MyFuture<int>'.
 //  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'MyFuture<int>'.
 //   MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                   ^
 //
@@ -36,7 +35,6 @@
   self::MyFuture<core::double*>* f = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3);
   self::MyFuture<core::int*>* f2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'MyFuture<int>'.
  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'MyFuture<int>'.
   MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
                                                   ^" in f as{TypeError} self::MyFuture<core::int*>*;
   self::MyFuture<core::num*>* f3 = self::foo().{self::MyFuture::then}<core::double*>((dynamic _) → core::double* => 2.3) as self::MyFuture<core::double*>*;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
index 1983524..e7c7bc4 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'Future<double>' can't be assigned to a variable of type 'Future<int>'.
 //  - 'Future' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
 //   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                 ^
 //
@@ -36,7 +35,6 @@
   asy::Future<core::double*>* f = self::foo().{asy::Future::then}<core::double*>((dynamic _) → core::double* => 2.3);
   asy::Future<core::int*>* f2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'Future<double>' can't be assigned to a variable of type 'Future<int>'.
  - 'Future' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
                                                 ^" in f as{TypeError} asy::Future<core::int*>*;
   asy::Future<core::num*>* f3 = self::foo().{asy::Future::then}<core::double*>((dynamic _) → core::double* => 2.3) as asy::Future<core::double*>*;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
index 1983524..e7c7bc4 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'Future<double>' can't be assigned to a variable of type 'Future<int>'.
 //  - 'Future' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
 //   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                 ^
 //
@@ -36,7 +35,6 @@
   asy::Future<core::double*>* f = self::foo().{asy::Future::then}<core::double*>((dynamic _) → core::double* => 2.3);
   asy::Future<core::int*>* f2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'Future<double>' can't be assigned to a variable of type 'Future<int>'.
  - 'Future' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
                                                 ^" in f as{TypeError} asy::Future<core::int*>*;
   asy::Future<core::num*>* f3 = self::foo().{asy::Future::then}<core::double*>((dynamic _) → core::double* => 2.3) as asy::Future<core::double*>*;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
index 81d1269..8c541ca 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_union_downwards.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
 //         new /*@ typeArgs=int* */ Future.value('hi'));
 //                                               ^
 //
@@ -35,7 +34,6 @@
 static field self::MyFuture<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} asy::FutureOr<core::int*>*));
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
index 68ec181..873f587 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_union_downwards.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
 //         new /*@ typeArgs=int* */ Future.value('hi'));
 //                                               ^
 //
@@ -35,7 +34,6 @@
 static field self::MyFuture<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} asy::FutureOr<core::int*>*));
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
index bb00772..a309a4b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
 //         new /*@ typeArgs=int* */ Future.value('hi'));
 //                                               ^
 //
@@ -35,7 +34,6 @@
 static field asy::Future<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} asy::FutureOr<core::int*>*));
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
index 66f2ce1..af242e2 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
 //         new /*@ typeArgs=int* */ Future.value('hi'));
 //                                               ^
 //
@@ -35,7 +34,6 @@
 static field asy::Future<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:47: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} asy::FutureOr<core::int*>*));
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]);
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect
index 44e61bf..d2a93e7 100644
--- a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect
@@ -3,22 +3,18 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:28:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*@ typeArgs=int* */ max(1, 2.0));
 //                                   ^
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:30:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*@ typeArgs=int* */ min(1, 2.0));
 //                                   ^
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:37: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   printInt(/*@ typeArgs=int* */ min("hi", "there"));
 //                                     ^
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:43: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   printInt(/*@ typeArgs=int* */ min("hi", "there"));
 //                                           ^
 //
@@ -42,20 +38,16 @@
   self::printInt(self::myMax(1, 2) as{TypeError} core::int*);
   self::printInt(self::myMax(1, 2) as core::int*);
   self::printInt(math::max<core::int*>(1, let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:28:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*@ typeArgs=int* */ max(1, 2.0));
                                   ^" in 2.0 as{TypeError} core::int*));
   self::printInt(math::min<core::int*>(1, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:30:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*@ typeArgs=int* */ min(1, 2.0));
                                   ^" in 2.0 as{TypeError} core::int*));
   self::printDouble(math::max<core::double*>(1.0, 2.0));
   self::printDouble(math::min<core::double*>(1.0, 2.0));
   self::printInt(math::min<core::int*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:37: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   printInt(/*@ typeArgs=int* */ min(\"hi\", \"there\"));
                                     ^" in "hi" as{TypeError} core::int*, let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:43: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   printInt(/*@ typeArgs=int* */ min(\"hi\", \"there\"));
                                           ^" in "there" as{TypeError} core::int*));
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
index 44e61bf..d2a93e7 100644
--- a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
@@ -3,22 +3,18 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:28:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*@ typeArgs=int* */ max(1, 2.0));
 //                                   ^
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:30:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*@ typeArgs=int* */ min(1, 2.0));
 //                                   ^
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:37: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   printInt(/*@ typeArgs=int* */ min("hi", "there"));
 //                                     ^
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:43: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   printInt(/*@ typeArgs=int* */ min("hi", "there"));
 //                                           ^
 //
@@ -42,20 +38,16 @@
   self::printInt(self::myMax(1, 2) as{TypeError} core::int*);
   self::printInt(self::myMax(1, 2) as core::int*);
   self::printInt(math::max<core::int*>(1, let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:28:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*@ typeArgs=int* */ max(1, 2.0));
                                   ^" in 2.0 as{TypeError} core::int*));
   self::printInt(math::min<core::int*>(1, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:30:35: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*@ typeArgs=int* */ min(1, 2.0));
                                   ^" in 2.0 as{TypeError} core::int*));
   self::printDouble(math::max<core::double*>(1.0, 2.0));
   self::printDouble(math::min<core::double*>(1.0, 2.0));
   self::printInt(math::min<core::int*>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:37: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   printInt(/*@ typeArgs=int* */ min(\"hi\", \"there\"));
                                     ^" in "hi" as{TypeError} core::int*, let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:37:43: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   printInt(/*@ typeArgs=int* */ min(\"hi\", \"there\"));
                                           ^" in "there" as{TypeError} core::int*));
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect
index ca2d8a1..0e19c3a 100644
--- a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*@ typeArgs=String* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
 //                                                                               ^
 //
@@ -15,7 +14,6 @@
 static method test() → dynamic {
   core::String* x = self::f<core::String*>(<core::String*>["hi"]);
   core::String* y = self::f<core::String*>(<core::String*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*@ typeArgs=String* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
                                                                               ^" in 42 as{TypeError} core::String*]);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
index ca2d8a1..0e19c3a 100644
--- a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*@ typeArgs=String* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
 //                                                                               ^
 //
@@ -15,7 +14,6 @@
 static method test() → dynamic {
   core::String* x = self::f<core::String*>(<core::String*>["hi"]);
   core::String* y = self::f<core::String*>(<core::String*>[let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           /*@ typeArgs=String* */ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
                                                                               ^" in 42 as{TypeError} core::String*]);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
index b10198f..899b8b0 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
@@ -3,32 +3,26 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
 //       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
 //                                                                         ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:30:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
 //                                                                         ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:46:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
 //   takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:47:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //   takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
 //           . /*@target=C::m*/ m);
 //                              ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //           . /*@target=C::m*/ m);
 //                              ^
 //
@@ -57,11 +51,9 @@
   self::takeDDO(#C1<core::double*>);
   self::takeOOI((#C1<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
   self::takeIDI(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
                                                                         ^" in (#C1<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
   self::takeDID(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:30:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
                                                                         ^" in (#C1<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
   self::takeOON((#C1<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
@@ -77,11 +69,9 @@
   self::takeDDO(#C2<core::double*>);
   self::takeOOI((#C2<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
   self::takeIDI(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:46:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
   takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
                                                                        ^" in (#C2<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
   self::takeDID(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:47:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
   takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
                                                                        ^" in (#C2<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
   self::takeOON((#C2<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
@@ -99,11 +89,9 @@
   self::takeOOO((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
   self::takeOOI((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
   self::takeIDI(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
           . /*@target=C::m*/ m);
                              ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
   self::takeDID(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
           . /*@target=C::m*/ m);
                              ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
index b10198f..899b8b0 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
@@ -3,32 +3,26 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
 //       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
 //                                                                         ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:30:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
 //                                                                         ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:46:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
 //   takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:47:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //   takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
 //           . /*@target=C::m*/ m);
 //                              ^
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //           . /*@target=C::m*/ m);
 //                              ^
 //
@@ -57,11 +51,9 @@
   self::takeDDO(#C1<core::double*>);
   self::takeOOI((#C1<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
   self::takeIDI(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
                                                                         ^" in (#C1<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
   self::takeDID(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:30:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
                                                                         ^" in (#C1<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
   self::takeOON((#C1<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
@@ -77,11 +69,9 @@
   self::takeDDO(#C2<core::double*>);
   self::takeOOI((#C2<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
   self::takeIDI(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:46:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
   takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
                                                                        ^" in (#C2<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
   self::takeDID(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:47:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
   takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
                                                                        ^" in (#C2<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
   self::takeOON((#C2<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
@@ -99,11 +89,9 @@
   self::takeOOO((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::num*);
   self::takeOOI((new self::C::•().{self::C::m}<core::Object*>) as{TypeError} (core::Object*, core::Object*) →* core::int*);
   self::takeIDI(let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
-Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
           . /*@target=C::m*/ m);
                              ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::double*, core::int*) →* core::int*);
   self::takeDID(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
-Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
           . /*@target=C::m*/ m);
                              ^" in (new self::C::•().{self::C::m}<core::num*>) as{TypeError} (core::int*, core::double*) →* core::double*);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect
index ab233fa..45a9f96 100644
--- a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           1.0);
 //           ^
 //
@@ -13,7 +12,6 @@
 static method f() → void {
   core::List<core::String*>* y;
   core::Iterable<core::String*>* x = y.{core::Iterable::map}<core::String*>((core::String* z) → core::String* => let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           1.0);
           ^" in 1.0 as{TypeError} core::String*);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
index ab233fa..45a9f96 100644
--- a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           1.0);
 //           ^
 //
@@ -13,7 +12,6 @@
 static method f() → void {
   core::List<core::String*>* y;
   core::Iterable<core::String*>* x = y.{core::Iterable::map}<core::String*>((core::String* z) → core::String* => let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
           1.0);
           ^" in 1.0 as{TypeError} core::String*);
 }
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect
index cf8de52..7967409 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect
@@ -10,7 +10,6 @@
 //
 // pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:111: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
 //                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
 //                                                                                                               ^
 //
@@ -32,7 +31,6 @@
                                                                                                                           ^" as{TypeError} asy::FutureOr<core::String*>*));
   asy::Future<core::String*>* results3 = results.{asy::Future::then}<core::String*>((core::List<core::int*>* list) → asy::FutureOr<core::String*>* => list.{core::Iterable::fold}<asy::FutureOr<core::String*>*>("", let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:111: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
                                                                                                               ^" in ((core::String* x, core::int* y) → core::String* => x.{core::String::+}(y.{core::int::toString}())) as{TypeError} (asy::FutureOr<core::String*>*, core::int*) →* asy::FutureOr<core::String*>*));
   asy::Future<core::String*>* results4 = results.{asy::Future::then}<core::String*>((core::List<core::int*>* list) → core::String* => list.{core::Iterable::fold}<core::String*>("", (core::String* x, core::int* y) → core::String* => x.{core::String::+}(y.{core::int::toString}())));
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
index cf8de52..7967409 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
@@ -10,7 +10,6 @@
 //
 // pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:111: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
 //                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
 //                                                                                                               ^
 //
@@ -32,7 +31,6 @@
                                                                                                                           ^" as{TypeError} asy::FutureOr<core::String*>*));
   asy::Future<core::String*>* results3 = results.{asy::Future::then}<core::String*>((core::List<core::int*>* list) → asy::FutureOr<core::String*>* => list.{core::Iterable::fold}<asy::FutureOr<core::String*>*>("", let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:111: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@ returnType=String* */ (String
                                                                                                               ^" in ((core::String* x, core::int* y) → core::String* => x.{core::String::+}(y.{core::int::toString}())) as{TypeError} (asy::FutureOr<core::String*>*, core::int*) →* asy::FutureOr<core::String*>*));
   asy::Future<core::String*>* results4 = results.{asy::Future::then}<core::String*>((core::List<core::int*>* list) → core::String* => list.{core::Iterable::fold}<core::String*>("", (core::String* x, core::int* y) → core::String* => x.{core::String::+}(y.{core::int::toString}())));
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
index 2d18242..bb7d545 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
 //                                                              ^
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
 //                                                              ^
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
 //                                                              ^
 //
@@ -42,18 +39,15 @@
   core::int* i;
   s = new self::B::•().{self::B::x} as{TypeError} core::String*;
   s = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
                                                              ^" in new self::B::•().{self::B::y} as{TypeError} core::String*;
   s = new self::B::•().{self::B::z};
   s = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
                                                              ^" in new self::B::•().{self::B::w} as{TypeError} core::String*;
   i = new self::B::•().{self::B::x} as{TypeError} core::int*;
   i = new self::B::•().{self::B::y};
   i = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
                                                              ^" in new self::B::•().{self::B::z} as{TypeError} core::int*;
   i = new self::B::•().{self::B::w};
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
index 2d18242..bb7d545 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
 //                                                              ^
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
 //                                                              ^
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
 //                                                              ^
 //
@@ -42,18 +39,15 @@
   core::int* i;
   s = new self::B::•().{self::B::x} as{TypeError} core::String*;
   s = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:21:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
                                                              ^" in new self::B::•().{self::B::y} as{TypeError} core::String*;
   s = new self::B::•().{self::B::z};
   s = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:23:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
                                                              ^" in new self::B::•().{self::B::w} as{TypeError} core::String*;
   i = new self::B::•().{self::B::x} as{TypeError} core::int*;
   i = new self::B::•().{self::B::y};
   i = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:27:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
                                                              ^" in new self::B::•().{self::B::z} as{TypeError} core::int*;
   i = new self::B::•().{self::B::w};
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
index 0dd5e96..8880525 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
@@ -18,69 +18,58 @@
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   a = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   b = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
 //  - 'Set' is from 'dart:core'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
 //   c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
 //                                                           ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
 //  - 'Set' is from 'dart:core'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
 //   c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
 //                                                           ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
 //   d = /*error:INVALID_ASSIGNMENT*/ 3;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
 //  - 'Map' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   g = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   h = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   j = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
 //  - 'List' is from 'dart:core'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
 //                                                          ^
 //
@@ -123,13 +112,11 @@
 static method test1() → dynamic {
   self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
   a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} self::A*;
   self::a = new self::B::•(3);
   self::b = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} self::B*;
   self::b = new self::B::•(3);
@@ -137,42 +124,35 @@
   self::c1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
  - 'Set' is from 'dart:core'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
   c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
                                                           ^" in (let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6) as{TypeError} core::List<dynamic>*;
   self::c2 = <dynamic>[];
   self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
  - 'Set' is from 'dart:core'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
   c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
                                                           ^" in (let final core::Set<dynamic>* #t8 = col::LinkedHashSet::•<dynamic>() in #t8) as{TypeError} core::List<dynamic>*;
   self::d = <dynamic, dynamic>{};
   self::d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
   d = /*error:INVALID_ASSIGNMENT*/ 3;
                                    ^" in 3 as{TypeError} core::Map<dynamic, dynamic>*;
   self::e = new self::A::•();
   self::e = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
  - 'Map' is from 'dart:core'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
   e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
                                                                   ^" in <dynamic, dynamic>{} as{TypeError} self::A*;
   self::f = 3;
   self::f = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} core::int*;
   self::g = 1;
   self::g = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   g = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} core::int*;
   self::h = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   h = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} self::B*;
   self::h = new self::B::•("b");
@@ -180,13 +160,11 @@
   self::j = new self::B::•("b");
   self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   j = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} self::B*;
   self::j = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
  - 'List' is from 'dart:core'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
                                                          ^" in <dynamic>[] as{TypeError} self::B*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
index 1766be7..4db29402 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
@@ -18,69 +18,58 @@
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   a = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   b = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
 //  - 'Set' is from 'dart:core'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
 //   c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
 //                                                           ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
 //  - 'Set' is from 'dart:core'.
 //  - 'List' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
 //   c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
 //                                                           ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
 //  - 'Map' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
 //   d = /*error:INVALID_ASSIGNMENT*/ 3;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
 //  - 'Map' is from 'dart:core'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   f = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   g = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   h = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   j = /*error:INVALID_ASSIGNMENT*/ false;
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
 //  - 'List' is from 'dart:core'.
 //  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
 //                                                          ^
 //
@@ -123,13 +112,11 @@
 static method test1() → dynamic {
   self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
   a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} self::A*;
   self::a = new self::B::•(3);
   self::b = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} self::B*;
   self::b = new self::B::•(3);
@@ -137,42 +124,35 @@
   self::c1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
  - 'Set' is from 'dart:core'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
   c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
                                                           ^" in (let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6) as{TypeError} core::List<dynamic>*;
   self::c2 = <dynamic>[];
   self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
  - 'Set' is from 'dart:core'.
  - 'List' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
   c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
                                                           ^" in (let final core::Set<dynamic>* #t8 = col::LinkedHashSet::•<dynamic>() in #t8) as{TypeError} core::List<dynamic>*;
   self::d = <dynamic, dynamic>{};
   self::d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
  - 'Map' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
   d = /*error:INVALID_ASSIGNMENT*/ 3;
                                    ^" in 3 as{TypeError} core::Map<dynamic, dynamic>*;
   self::e = new self::A::•();
   self::e = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
  - 'Map' is from 'dart:core'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
   e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
                                                                   ^" in <dynamic, dynamic>{} as{TypeError} self::A*;
   self::f = 3;
   self::f = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} core::int*;
   self::g = 1;
   self::g = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   g = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} core::int*;
   self::h = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   h = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} self::B*;
   self::h = new self::B::•("b");
@@ -180,13 +160,11 @@
   self::j = new self::B::•("b");
   self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   j = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} self::B*;
   self::j = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
  - 'List' is from 'dart:core'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B'.
   j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
                                                          ^" in <dynamic>[] as{TypeError} self::B*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
index a041075..26971fe 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:14:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   y = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -21,11 +19,9 @@
 static field core::int* y = inf::x;
 static method test1() → dynamic {
   inf::x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   self::y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:14:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   y = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
index a041075..26971fe 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:14:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   y = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -21,11 +19,9 @@
 static field core::int* y = inf::x;
 static method test1() → dynamic {
   inf::x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   self::y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:14:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   y = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
index 83a033e..adb045f 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   A.x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   B.y = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
@@ -26,11 +24,9 @@
 }
 static method test1() → dynamic {
   inf::A::x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   A.x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
   self::B::y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   B.y = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
index 83a033e..adb045f 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   A.x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   B.y = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
@@ -26,11 +24,9 @@
 }
 static method test1() → dynamic {
   inf::A::x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   A.x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
   self::B::y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   B.y = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
index 9afb6a2..e2dd820 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
 //
@@ -25,7 +24,6 @@
 }
 static method foo() → dynamic {
   core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
                                                                     ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
   core::int* z = new self::B::•().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
index 9afb6a2..e2dd820 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
 //
@@ -25,7 +24,6 @@
 }
 static method foo() → dynamic {
   core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
                                                                     ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
   core::int* z = new self::B::•().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
index d26cb7a..75a45d2 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
 //
@@ -25,7 +24,6 @@
 }
 static method foo() → dynamic {
   core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
                                                                     ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
   core::int* z = new self::B::•().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
index d26cb7a..75a45d2 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
 //
@@ -25,7 +24,6 @@
 }
 static method foo() → dynamic {
   core::String* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
                                                                     ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
   core::int* z = new self::B::•().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect
index 6a786ef..84f5869 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -13,7 +12,6 @@
 static method test1() → dynamic {
   core::int* x = 3;
   x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
index 6a786ef..84f5869 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -13,7 +12,6 @@
 static method test1() → dynamic {
   core::int* x = 3;
   x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect
index 3249285..d6ac624 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -13,7 +12,6 @@
 static method test2() → dynamic {
   core::int* x = 3;
   x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
index 3249285..d6ac624 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -13,7 +12,6 @@
 static method test2() → dynamic {
   core::int* x = 3;
   x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect
index d3cee19..3476cd7 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     a = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     b = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:19:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     c = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
@@ -30,19 +27,16 @@
   method test1() → dynamic {
     core::int* a = this.{self::A::x};
     a = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
     a = 3;
     core::int* b = this.{self::A::y};
     b = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
     b = 4;
     core::int* c = this.{self::A::z};
     c = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:19:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     c = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
     c = 4;
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
index d3cee19..3476cd7 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     a = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     b = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:19:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     c = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
 //
@@ -30,19 +27,16 @@
   method test1() → dynamic {
     core::int* a = this.{self::A::x};
     a = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
     a = 3;
     core::int* b = this.{self::A::y};
     b = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
     b = 4;
     core::int* c = this.{self::A::z};
     c = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:19:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     c = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                      ^" in "hi" as{TypeError} core::int*;
     c = 4;
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect
index 347287a..74c22b4 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:15:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   b = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:18:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   c = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -26,19 +23,16 @@
 static method test1() → dynamic {
   core::int* a = self::x;
   a = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   a = 3;
   core::int* b = self::y;
   b = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:15:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   b = 4;
   core::int* c = self::z;
   c = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:18:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   c = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   c = 4;
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
index 347287a..74c22b4 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:15:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   b = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:18:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   c = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
 //
@@ -26,19 +23,16 @@
 static method test1() → dynamic {
   core::int* a = self::x;
   a = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   a = 3;
   core::int* b = self::y;
   b = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:15:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   b = 4;
   core::int* c = self::z;
   c = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:18:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   c = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} core::int*;
   c = 4;
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
index 759a5f0..eead399 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
 //                                                                     ^
 //
@@ -30,7 +29,6 @@
 static method foo() → dynamic {
   core::int* y = new self::C::•().{self::C::x};
   core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
                                                                     ^" in new self::C::•().{self::C::x} as{TypeError} core::String*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
index 759a5f0..eead399 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
 //                                                                     ^
 //
@@ -30,7 +29,6 @@
 static method foo() → dynamic {
   core::int* y = new self::C::•().{self::C::x};
   core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
                                                                     ^" in new self::C::•().{self::C::x} as{TypeError} core::String*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
index 32fb9c9..e011236 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
@@ -16,7 +16,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
 //                                                                     ^
 //
@@ -43,7 +42,6 @@
 static method foo() → dynamic {
   core::int* y = new test::C::•().{test::C::x};
   core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
                                                                     ^" in new test::C::•().{test::C::x} as{TypeError} core::String*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
index 32fb9c9..e011236 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
@@ -16,7 +16,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
 //                                                                     ^
 //
@@ -43,7 +42,6 @@
 static method foo() → dynamic {
   core::int* y = new test::C::•().{test::C::x};
   core::String* z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
                                                                     ^" in new test::C::•().{test::C::x} as{TypeError} core::String*;
 }
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
index ceadc8a..9ba269b 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   get w => /*error:RETURN_OF_INVALID_TYPE*/ "hello";
 //                                             ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
 //
@@ -30,13 +28,11 @@
     return 3;
   get w() → core::int*
     return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   get w => /*error:RETURN_OF_INVALID_TYPE*/ \"hello\";
                                             ^" in "hello" as{TypeError} core::int*;
 }
 static method foo() → dynamic {
   core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
                                                                     ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
   core::int* z = new self::B::•().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
index ceadc8a..9ba269b 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   get w => /*error:RETURN_OF_INVALID_TYPE*/ "hello";
 //                                             ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
 //
@@ -30,13 +28,11 @@
     return 3;
   get w() → core::int*
     return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   get w => /*error:RETURN_OF_INVALID_TYPE*/ \"hello\";
                                             ^" in "hello" as{TypeError} core::int*;
 }
 static method foo() → dynamic {
   core::String* y = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
                                                                     ^" in new self::B::•().{self::B::x} as{TypeError} core::String*;
   core::int* z = new self::B::•().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
index b926ab0..6bfd5ee 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
 //                                                                          ^
 //
@@ -26,7 +25,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
                                                                          ^" in new self::B::•<core::String*>().{self::B::x} as{TypeError} core::int*;
   core::String* z = new self::B::•<core::String*>().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
index b926ab0..6bfd5ee 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
 //                                                                          ^
 //
@@ -26,7 +25,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
                                                                          ^" in new self::B::•<core::String*>().{self::B::x} as{TypeError} core::int*;
   core::String* z = new self::B::•<core::String*>().{self::B::x};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
index f2818be..fcd1d67 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=B::m*/ m(null, null);
 //                          ^
 //
@@ -38,7 +37,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       . /*@target=B::m*/ m(null, null);
                          ^" in new self::B::•<dynamic>().{self::B::m}(null, null) as{TypeError} core::int*;
   core::String* z = new self::B::•<dynamic>().{self::B::m}(null, null);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
index f2818be..fcd1d67 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=B::m*/ m(null, null);
 //                          ^
 //
@@ -38,7 +37,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       . /*@target=B::m*/ m(null, null);
                          ^" in new self::B::•<dynamic>().{self::B::m}(null, null) as{TypeError} core::int*;
   core::String* z = new self::B::•<dynamic>().{self::B::m}(null, null);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
index 59fb457..62bff19 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=A::value*/ value;
 //                              ^
 //
@@ -35,7 +34,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       . /*@target=A::value*/ value;
                              ^" in new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value} as{TypeError} core::int*;
   core::String* z = new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
index 59fb457..62bff19 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=A::value*/ value;
 //                              ^
 //
@@ -35,7 +34,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       . /*@target=A::value*/ value;
                              ^" in new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value} as{TypeError} core::int*;
   core::String* z = new self::B::•<core::String*>().{self::B::m}(null, null).{self::A::value};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
index 0351235..fe2a499 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
@@ -18,7 +18,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=A::value*/ value;
 //                              ^
 //
@@ -50,7 +49,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       . /*@target=A::value*/ value;
                              ^" in new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int*;
   core::String* z = new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
index 0351235..fe2a499 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
@@ -18,7 +18,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=A::value*/ value;
 //                              ^
 //
@@ -50,7 +49,6 @@
 }
 static method foo() → dynamic {
   core::int* y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       . /*@target=A::value*/ value;
                              ^" in new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int*;
   core::String* z = new test::B::•<core::String*>().{test::B::m}(null, null).{test::A::value};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect
index cd22a1d..12a0f49 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect
@@ -3,18 +3,15 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:23:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:32:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
 //  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     String y = /*error:INVALID_ASSIGNMENT*/ x;
 //                                             ^
 //
@@ -47,7 +44,6 @@
   method foo(generic-covariant-impl self::Bar::T* t) → void {
     for (core::String* i in t) {
       core::int* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
     }
@@ -60,7 +56,6 @@
   method foo(generic-covariant-impl self::Baz::S* t) → void {
     for (self::Baz::T* i in t) {
       core::int* x = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:23:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
       self::Baz::T* y = i;
@@ -72,7 +67,6 @@
   for (self::Foo* x in list) {
     core::String* y = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:32:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     String y = /*error:INVALID_ASSIGNMENT*/ x;
                                             ^" in x as{TypeError} core::String*;
   }
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
index cd22a1d..12a0f49 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
@@ -3,18 +3,15 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:23:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:32:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
 //  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     String y = /*error:INVALID_ASSIGNMENT*/ x;
 //                                             ^
 //
@@ -47,7 +44,6 @@
   method foo(generic-covariant-impl self::Bar::T* t) → void {
     for (core::String* i in t) {
       core::int* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
     }
@@ -60,7 +56,6 @@
   method foo(generic-covariant-impl self::Baz::S* t) → void {
     for (self::Baz::T* i in t) {
       core::int* x = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:23:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
       self::Baz::T* y = i;
@@ -72,7 +67,6 @@
   for (self::Foo* x in list) {
     core::String* y = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:32:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     String y = /*error:INVALID_ASSIGNMENT*/ x;
                                             ^" in x as{TypeError} core::String*;
   }
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect
index cf89449..ab6817c 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect
@@ -3,18 +3,15 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
 //  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     String y = /*error:INVALID_ASSIGNMENT*/ x;
 //                                             ^
 //
@@ -50,7 +47,6 @@
   method foo(generic-covariant-impl self::Bar::T* t) → dynamic async {
     await for (core::String* i in t) {
       core::int* x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
     }
@@ -63,7 +59,6 @@
   method foo(generic-covariant-impl self::Baz::S* t) → dynamic async {
     await for (self::Baz::T* i in t) {
       core::int* x = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
       self::Baz::T* y = i;
@@ -79,7 +74,6 @@
   await for (self::Foo* x in myStream) {
     core::String* y = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     String y = /*error:INVALID_ASSIGNMENT*/ x;
                                             ^" in x as{TypeError} core::String*;
   }
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
index 87def0a..55072fa 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
@@ -3,18 +3,15 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       int x = /*error:INVALID_ASSIGNMENT*/ i;
 //                                            ^
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
 //  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     String y = /*error:INVALID_ASSIGNMENT*/ x;
 //                                             ^
 //
@@ -76,7 +73,6 @@
                   core::String* i = :for-iterator.{asy::_StreamIterator::current};
                   {
                     core::int* x = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
                   }
@@ -137,7 +133,6 @@
                   self::Baz::T* i = :for-iterator.{asy::_StreamIterator::current};
                   {
                     core::int* x = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
                                            ^" in i as{TypeError} core::int*;
                     self::Baz::T* y = i;
@@ -201,7 +196,6 @@
                 {
                   core::String* y = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
     String y = /*error:INVALID_ASSIGNMENT*/ x;
                                             ^" in x as{TypeError} core::String*;
                 }
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect
index 3edce78..3caa837 100644
--- a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ "1"]);
 //                                              ^
 //
@@ -13,7 +12,6 @@
 class Foo extends core::Object {
   field core::int* x = 1;
   constructor •([core::int* x = invalid-expression "pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ \"1\"]);
                                              ^"]) → self::Foo*
     : self::Foo::x = x, super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
index 3edce78..3caa837 100644
--- a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ "1"]);
 //                                              ^
 //
@@ -13,7 +12,6 @@
 class Foo extends core::Object {
   field core::int* x = 1;
   constructor •([core::int* x = invalid-expression "pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ \"1\"]);
                                              ^"]) → self::Foo*
     : self::Foo::x = x, super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect
index 26a93d8..11fc86a 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:10:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //   func = f.call;
 //            ^
 //
@@ -13,7 +12,6 @@
 static method test(<T extends core::Object* = dynamic>(T*) →* T* f) → void {
   (core::int*) →* core::int* func;
   func = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:10:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
   func = f.call;
            ^" in f.call as{TypeError} (core::int*) →* core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
index 89d9a84..2c8a187 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                       ^
 //
@@ -23,11 +20,9 @@
 static method test1() → dynamic {
   core::List<core::int*>* x = <core::int*>[1, 2, 3];
   x.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                       ^" in "hi" as{TypeError} core::int*);
   x.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
                                                                       ^" in 4.0 as{TypeError} core::int*);
   x.{core::List::add}(4);
@@ -36,7 +31,6 @@
 static method test2() → dynamic {
   core::List<core::num*>* x = <core::num*>[1, 2.0, 3];
   x.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                       ^" in "hi" as{TypeError} core::num*);
   x.{core::List::add}(4.0);
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
index 89d9a84..2c8a187 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
 //                                                                       ^
 //
 // pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                       ^
 //
@@ -23,11 +20,9 @@
 static method test1() → dynamic {
   core::List<core::int*>* x = <core::int*>[1, 2, 3];
   x.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                       ^" in "hi" as{TypeError} core::int*);
   x.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
                                                                       ^" in 4.0 as{TypeError} core::int*);
   x.{core::List::add}(4);
@@ -36,7 +31,6 @@
 static method test2() → dynamic {
   core::List<core::num*>* x = <core::num*>[1, 2.0, 3];
   x.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                       ^" in "hi" as{TypeError} core::num*);
   x.{core::List::add}(4.0);
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
index 2578c7b..e24becc 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //   x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                        ^
 //
@@ -24,11 +21,9 @@
 static field core::List<core::num*>* x2 = <core::num*>[1, 2.0, 3];
 static method test1() → dynamic {
   self::x1.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                        ^" in "hi" as{TypeError} core::int*);
   self::x1.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
                                                                        ^" in 4.0 as{TypeError} core::int*);
   self::x1.{core::List::add}(4);
@@ -36,7 +31,6 @@
 }
 static method test2() → dynamic {
   self::x2.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
   x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                        ^" in "hi" as{TypeError} core::num*);
   self::x2.{core::List::add}(4.0);
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
index 2578c7b..e24becc 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
@@ -3,17 +3,14 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
 //                                                                        ^
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //   x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                        ^
 //
@@ -24,11 +21,9 @@
 static field core::List<core::num*>* x2 = <core::num*>[1, 2.0, 3];
 static method test1() → dynamic {
   self::x1.{core::List::add}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                        ^" in "hi" as{TypeError} core::int*);
   self::x1.{core::List::add}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
                                                                        ^" in 4.0 as{TypeError} core::int*);
   self::x1.{core::List::add}(4);
@@ -36,7 +31,6 @@
 }
 static method test2() → dynamic {
   self::x2.{core::List::add}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
   x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
                                                                        ^" in "hi" as{TypeError} core::num*);
   self::x2.{core::List::add}(4.0);
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
index 603476d..1a8ef87 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
 //     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                      ^
 //
@@ -22,7 +21,6 @@
   function b() → asy::Future<(core::int*) →* core::int*>* async {
     return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                      ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
   }
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
index 34219f6..02cb679 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
 //     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                      ^
 //
@@ -33,7 +32,6 @@
         {
           :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                      ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
           break #L1;
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
index 2449679..1f1aeac 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
@@ -3,28 +3,23 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
 //                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
 //  - 'Pattern' is from 'dart:core'.
-// Try changing the type of the parameter, or casting the argument to 'Pattern'.
 //   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                             ^
 //
@@ -35,15 +30,12 @@
   core::Map<core::int*, core::String*>* x = <core::int*, core::String*>{1: "x", 2: "y"};
   x.{core::Map::[]=}(3, "z");
   x.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                              ^" in "hi" as{TypeError} core::int*, "w");
   x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
                                              ^" in 4.0 as{TypeError} core::int*, "u");
   x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                             ^" in 42 as{TypeError} core::String*);
   core::Map<core::num*, core::String*>* y = x;
@@ -52,13 +44,11 @@
   core::Map<core::num*, core::Pattern*>* x = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
   x.{core::Map::[]=}(3, "z");
   x.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                              ^" in "hi" as{TypeError} core::num*, "w");
   x.{core::Map::[]=}(4.0, "u");
   x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
  - 'Pattern' is from 'dart:core'.
-Try changing the type of the parameter, or casting the argument to 'Pattern'.
   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                             ^" in 42 as{TypeError} core::Pattern*);
   core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
index 2449679..1f1aeac 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
@@ -3,28 +3,23 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
 //                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                             ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
 //  - 'Pattern' is from 'dart:core'.
-// Try changing the type of the parameter, or casting the argument to 'Pattern'.
 //   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                             ^
 //
@@ -35,15 +30,12 @@
   core::Map<core::int*, core::String*>* x = <core::int*, core::String*>{1: "x", 2: "y"};
   x.{core::Map::[]=}(3, "z");
   x.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                              ^" in "hi" as{TypeError} core::int*, "w");
   x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
                                              ^" in 4.0 as{TypeError} core::int*, "u");
   x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                             ^" in 42 as{TypeError} core::String*);
   core::Map<core::num*, core::String*>* y = x;
@@ -52,13 +44,11 @@
   core::Map<core::num*, core::Pattern*>* x = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
   x.{core::Map::[]=}(3, "z");
   x.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                              ^" in "hi" as{TypeError} core::num*, "w");
   x.{core::Map::[]=}(4.0, "u");
   x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
  - 'Pattern' is from 'dart:core'.
-Try changing the type of the parameter, or casting the argument to 'Pattern'.
   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                             ^" in 42 as{TypeError} core::Pattern*);
   core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
index 7af3179..4505766 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
@@ -3,28 +3,23 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //   x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //   x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
 //  - 'Pattern' is from 'dart:core'.
-// Try changing the type of the parameter, or casting the argument to 'Pattern'.
 //   x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                              ^
 //
@@ -36,15 +31,12 @@
 static method test1() → dynamic {
   self::x1.{core::Map::[]=}(3, "z");
   self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                                                   ^" in "hi" as{TypeError} core::int*, "w");
   self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
                                                                   ^" in 4.0 as{TypeError} core::int*, "u");
   self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
   x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                              ^" in 42 as{TypeError} core::String*);
   core::Map<core::num*, core::String*>* y = self::x1;
@@ -52,13 +44,11 @@
 static method test2() → dynamic {
   self::x2.{core::Map::[]=}(3, "z");
   self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
   x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                                                   ^" in "hi" as{TypeError} core::num*, "w");
   self::x2.{core::Map::[]=}(4.0, "u");
   self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
  - 'Pattern' is from 'dart:core'.
-Try changing the type of the parameter, or casting the argument to 'Pattern'.
   x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                              ^" in 42 as{TypeError} core::Pattern*);
   core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
index 7af3179..4505766 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
@@ -3,28 +3,23 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-// Try changing the type of the parameter, or casting the argument to 'int'.
 //   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-// Try changing the type of the parameter, or casting the argument to 'String'.
 //   x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                              ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-// Try changing the type of the parameter, or casting the argument to 'num'.
 //   x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
 //                                                                   ^
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
 //  - 'Pattern' is from 'dart:core'.
-// Try changing the type of the parameter, or casting the argument to 'Pattern'.
 //   x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                              ^
 //
@@ -36,15 +31,12 @@
 static method test1() → dynamic {
   self::x1.{core::Map::[]=}(3, "z");
   self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                                                   ^" in "hi" as{TypeError} core::int*, "w");
   self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
-Try changing the type of the parameter, or casting the argument to 'int'.
   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
                                                                   ^" in 4.0 as{TypeError} core::int*, "u");
   self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
-Try changing the type of the parameter, or casting the argument to 'String'.
   x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                              ^" in 42 as{TypeError} core::String*);
   core::Map<core::num*, core::String*>* y = self::x1;
@@ -52,13 +44,11 @@
 static method test2() → dynamic {
   self::x2.{core::Map::[]=}(3, "z");
   self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
-Try changing the type of the parameter, or casting the argument to 'num'.
   x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
                                                                   ^" in "hi" as{TypeError} core::num*, "w");
   self::x2.{core::Map::[]=}(4.0, "u");
   self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
  - 'Pattern' is from 'dart:core'.
-Try changing the type of the parameter, or casting the argument to 'Pattern'.
   x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
                                                              ^" in 42 as{TypeError} core::Pattern*);
   core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
index a896508..0353c68 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                                         ^
 //
 // pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                                         ^
 //
@@ -24,12 +22,10 @@
 static method test5() → dynamic {
   self::A* a1 = new self::A::•();
   a1.{self::A::x} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                                         ^" in "hi" as{TypeError} core::int*;
   self::A* a2 = new self::A::•();
   a2.{self::A::x} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                                         ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
index a896508..0353c68 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                                         ^
 //
 // pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                                         ^
 //
@@ -24,12 +22,10 @@
 static method test5() → dynamic {
   self::A* a1 = new self::A::•();
   a1.{self::A::x} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                                         ^" in "hi" as{TypeError} core::int*;
   self::A* a2 = new self::A::•();
   a2.{self::A::x} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
   a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                                         ^" in "hi" as{TypeError} core::int*;
 }
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
index 6c9873d..a34ea59 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
 //   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                    ^
 //
@@ -21,7 +20,6 @@
 static method b() → asy::Future<(core::int*) →* core::int*>* async {
   return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                    ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
 }
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
index d2f7099..0dba3ea 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -4,7 +4,6 @@
 //
 // pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
 //  - 'FutureOr' is from 'dart:async'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
 //   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
 //                                    ^
 //
@@ -32,7 +31,6 @@
       {
         :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'FutureOr' is from 'dart:async'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
                                    ^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
         break #L1;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect
index 67be699..1f7e3c2 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect
@@ -2,8 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:19: Error: An equality expression can't be an operand of another equality expression.
-// Try re-writing the expression.
+// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:19: Error: A comparison expression can't be an operand of another comparison expression.
+// Try putting parentheses around one of the comparisons.
 // var v = (f<dynamic>)(() {
 //                   ^
 //
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect
index 8c4c41b..973e1f4 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect
@@ -2,8 +2,8 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:15: Error: An equality expression can't be an operand of another equality expression.
-// Try re-writing the expression.
+// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:15: Error: A comparison expression can't be an operand of another comparison expression.
+// Try putting parentheses around one of the comparisons.
 // var v = (f<int>)(() {
 //               ^
 //
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
index 82e6557..4468732 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
@@ -3,37 +3,30 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:108:34: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //             /*@ target=num::+ */ += getInt();
 //                                  ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:118:53: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //     var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
 //                                                     ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:122:36: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //         ['x'] /*@ target=num::+ */ ++;
 //                                    ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //             /*@ target=double::+ */ += getInt();
 //                                     ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:252:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //             /*@ target=double::+ */ += getNum();
 //                                     ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:59: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
 //                                                           ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:259:43: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //             ['x'] /*@ target=double::+ */ ++;
 //                                           ^
 //
@@ -94,17 +87,14 @@
     core::num* v5 = let final core::String* #t69 = "x" in let final core::int* #t70 = super.{self::Base::[]}(#t69) in #t70.{core::num::==}(null) ?{core::num*} let final core::num* #t71 = self::getNum() as{TypeError} core::double* in let final void #t72 = super.{self::Base::[]=}(#t69, #t71) in #t71 : #t70;
     core::num* v6 = let final core::String* #t73 = "x" in let final core::int* #t74 = super.{self::Base::[]}(#t73) in #t74.{core::num::==}(null) ?{core::num*} let final core::double* #t75 = self::getDouble() in let final void #t76 = super.{self::Base::[]=}(#t73, #t75) in #t75 : #t74;
     core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:108:34: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
             /*@ target=num::+ */ += getInt();
                                  ^" in super.{self::Base::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = super.{self::Base::[]=}(#t77, #t78) in #t78;
     core::num* v8 = let final core::String* #t81 = "x" in let final core::num* #t82 = super.{self::Base::[]}(#t81).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t83 = super.{self::Base::[]=}(#t81, #t82) in #t82;
     core::double* v9 = let final core::String* #t84 = "x" in let final core::double* #t85 = super.{self::Base::[]}(#t84).{core::num::+}(self::getDouble()) in let final void #t86 = super.{self::Base::[]=}(#t84, #t85) in #t85;
     core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:118:53: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
     var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
                                                     ^" in super.{self::Base::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = super.{self::Base::[]=}(#t87, #t88) in #t88;
     core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = super.{self::Base::[]}(#t91) in let final void #t93 = super.{self::Base::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:122:36: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
         ['x'] /*@ target=num::+ */ ++;
                                    ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
   }
@@ -168,19 +158,15 @@
     core::num* v4 = let final core::String* #t192 = "x" in let final core::double* #t193 = super.{self::Base::[]}(#t192) in #t193.{core::num::==}(null) ?{core::num*} let final core::int* #t194 = self::getInt() in let final void #t195 = super.{self::Base::[]=}(#t192, #t194) in #t194 : #t193;
     core::num* v5 = let final core::String* #t196 = "x" in let final core::double* #t197 = super.{self::Base::[]}(#t196) in #t197.{core::num::==}(null) ?{core::num*} let final core::num* #t198 = self::getNum() as{TypeError} core::int* in let final void #t199 = super.{self::Base::[]=}(#t196, #t198) in #t198 : #t197;
     core::double* v7 = let final core::String* #t200 = "x" in let final core::double* #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
             /*@ target=double::+ */ += getInt();
                                     ^" in super.{self::Base::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = super.{self::Base::[]=}(#t200, #t201) in #t201;
     core::double* v8 = let final core::String* #t204 = "x" in let final core::double* #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:252:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
             /*@ target=double::+ */ += getNum();
                                     ^" in super.{self::Base::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = super.{self::Base::[]=}(#t204, #t205) in #t205;
     core::double* v10 = let final core::String* #t208 = "x" in let final core::double* #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:59: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
                                                           ^" in super.{self::Base::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = super.{self::Base::[]=}(#t208, #t209) in #t209;
     core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = super.{self::Base::[]}(#t212) in let final void #t214 = super.{self::Base::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:259:43: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
             ['x'] /*@ target=double::+ */ ++;
                                           ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
   }
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
index 805d030..e9c7b8e 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
@@ -3,37 +3,30 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:111:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //         /*@target=num::+*/ += getInt();
 //                            ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:121:51: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //     var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
 //                                                   ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //         /*@target=num::+*/ ++;
 //                            ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //         /*@target=double::+*/ += getInt();
 //                               ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:272:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //         /*@target=double::+*/ += getNum();
 //                               ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:274:57: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
 //                                                         ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:279:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //         /*@target=double::+*/ ++;
 //                               ^
 //
@@ -89,17 +82,14 @@
     core::num* v5 = let final core::String* #t76 = "x" in let final core::int* #t77 = this.{self::Test3::[]}(#t76) in #t77.{core::num::==}(null) ?{core::num*} let final core::num* #t78 = self::getNum() as{TypeError} core::double* in let final void #t79 = this.{self::Test3::[]=}(#t76, #t78) in #t78 : #t77;
     core::num* v6 = let final core::String* #t80 = "x" in let final core::int* #t81 = this.{self::Test3::[]}(#t80) in #t81.{core::num::==}(null) ?{core::num*} let final core::double* #t82 = self::getDouble() in let final void #t83 = this.{self::Test3::[]=}(#t80, #t82) in #t82 : #t81;
     core::int* v7 = let final core::String* #t84 = "x" in let final core::int* #t85 = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:111:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
         /*@target=num::+*/ += getInt();
                            ^" in this.{self::Test3::[]}(#t84).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t87 = this.{self::Test3::[]=}(#t84, #t85) in #t85;
     core::num* v8 = let final core::String* #t88 = "x" in let final core::num* #t89 = this.{self::Test3::[]}(#t88).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t90 = this.{self::Test3::[]=}(#t88, #t89) in #t89;
     core::double* v9 = let final core::String* #t91 = "x" in let final core::double* #t92 = this.{self::Test3::[]}(#t91).{core::num::+}(self::getDouble()) in let final void #t93 = this.{self::Test3::[]=}(#t91, #t92) in #t92;
     core::int* v10 = let final core::String* #t94 = "x" in let final core::int* #t95 = let final<BottomType> #t96 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:121:51: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
     var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
                                                   ^" in this.{self::Test3::[]}(#t94).{core::num::+}(1) as{TypeError} core::double* in let final void #t97 = this.{self::Test3::[]=}(#t94, #t95) in #t95;
     core::int* v11 = let final core::String* #t98 = "x" in let final core::int* #t99 = this.{self::Test3::[]}(#t98) in let final void #t100 = this.{self::Test3::[]=}(#t98, let final<BottomType> #t101 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
         /*@target=num::+*/ ++;
                            ^" in #t99.{core::num::+}(1) as{TypeError} core::double*) in #t99;
   }
@@ -171,19 +161,15 @@
     core::num* v4 = let final core::String* #t208 = "x" in let final core::double* #t209 = this.{self::Test7::[]}(#t208) in #t209.{core::num::==}(null) ?{core::num*} let final core::int* #t210 = self::getInt() in let final void #t211 = this.{self::Test7::[]=}(#t208, #t210) in #t210 : #t209;
     core::num* v5 = let final core::String* #t212 = "x" in let final core::double* #t213 = this.{self::Test7::[]}(#t212) in #t213.{core::num::==}(null) ?{core::num*} let final core::num* #t214 = self::getNum() as{TypeError} core::int* in let final void #t215 = this.{self::Test7::[]=}(#t212, #t214) in #t214 : #t213;
     core::double* v7 = let final core::String* #t216 = "x" in let final core::double* #t217 = let final<BottomType> #t218 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
         /*@target=double::+*/ += getInt();
                               ^" in this.{self::Test7::[]}(#t216).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t219 = this.{self::Test7::[]=}(#t216, #t217) in #t217;
     core::double* v8 = let final core::String* #t220 = "x" in let final core::double* #t221 = let final<BottomType> #t222 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:272:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
         /*@target=double::+*/ += getNum();
                               ^" in this.{self::Test7::[]}(#t220).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t223 = this.{self::Test7::[]=}(#t220, #t221) in #t221;
     core::double* v10 = let final core::String* #t224 = "x" in let final core::double* #t225 = let final<BottomType> #t226 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:274:57: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
     var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
                                                         ^" in this.{self::Test7::[]}(#t224).{core::double::+}(1) as{TypeError} core::int* in let final void #t227 = this.{self::Test7::[]=}(#t224, #t225) in #t225;
     core::double* v11 = let final core::String* #t228 = "x" in let final core::double* #t229 = this.{self::Test7::[]}(#t228) in let final void #t230 = this.{self::Test7::[]=}(#t228, let final<BottomType> #t231 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:279:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
         /*@target=double::+*/ ++;
                               ^" in #t229.{core::double::+}(1) as{TypeError} core::int*) in #t229;
   }
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
index 7ee2c5a..7eb4b1c 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
@@ -3,37 +3,30 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //       t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
 //                                                                               ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //       /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
 //                            ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-// Try changing the type of the left hand side, or casting the right hand side to 'double'.
 //       'x'] /*@ target=num::+ */ ++;
 //                                 ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       'x'] /*@ target=double::+ */ += getInt();
 //                                    ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:214:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       'x'] /*@ target=double::+ */ += getNum();
 //                                    ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:217:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*@ target=double::+ */ ++t
 //                               ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:221:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       'x'] /*@ target=double::+ */ ++;
 //                                    ^
 //
@@ -82,17 +75,14 @@
   core::num* v5 = let final self::Test<core::int*, core::double*>* #t90 = t in let final core::String* #t91 = "x" in let final core::int* #t92 = #t90.{self::Test::[]}(#t91) in #t92.{core::num::==}(null) ?{core::num*} let final core::num* #t93 = self::getNum() as{TypeError} core::double* in let final void #t94 = #t90.{self::Test::[]=}(#t91, #t93) in #t93 : #t92;
   core::num* v6 = let final self::Test<core::int*, core::double*>* #t95 = t in let final core::String* #t96 = "x" in let final core::int* #t97 = #t95.{self::Test::[]}(#t96) in #t97.{core::num::==}(null) ?{core::num*} let final core::double* #t98 = self::getDouble() in let final void #t99 = #t95.{self::Test::[]=}(#t96, #t98) in #t98 : #t97;
   core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
       t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
                                                                               ^" in #t100.{self::Test::[]}(#t101).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t104 = #t100.{self::Test::[]=}(#t101, #t102) in #t102;
   core::num* v8 = let final self::Test<core::int*, core::double*>* #t105 = t in let final core::String* #t106 = "x" in let final core::num* #t107 = #t105.{self::Test::[]}(#t106).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t108 = #t105.{self::Test::[]=}(#t106, #t107) in #t107;
   core::double* v9 = let final self::Test<core::int*, core::double*>* #t109 = t in let final core::String* #t110 = "x" in let final core::double* #t111 = #t109.{self::Test::[]}(#t110).{core::num::+}(self::getDouble()) in let final void #t112 = #t109.{self::Test::[]=}(#t110, #t111) in #t111;
   core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
       /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
                            ^" in #t113.{self::Test::[]}(#t114).{core::num::+}(1) as{TypeError} core::double* in let final void #t117 = #t113.{self::Test::[]=}(#t114, #t115) in #t115;
   core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
-Try changing the type of the left hand side, or casting the right hand side to 'double'.
       'x'] /*@ target=num::+ */ ++;
                                 ^" in #t120.{core::num::+}(1) as{TypeError} core::double*) in #t120;
 }
@@ -136,19 +126,15 @@
   core::num* v4 = let final self::Test<core::double*, core::int*>* #t250 = t in let final core::String* #t251 = "x" in let final core::double* #t252 = #t250.{self::Test::[]}(#t251) in #t252.{core::num::==}(null) ?{core::num*} let final core::int* #t253 = self::getInt() in let final void #t254 = #t250.{self::Test::[]=}(#t251, #t253) in #t253 : #t252;
   core::num* v5 = let final self::Test<core::double*, core::int*>* #t255 = t in let final core::String* #t256 = "x" in let final core::double* #t257 = #t255.{self::Test::[]}(#t256) in #t257.{core::num::==}(null) ?{core::num*} let final core::num* #t258 = self::getNum() as{TypeError} core::int* in let final void #t259 = #t255.{self::Test::[]=}(#t256, #t258) in #t258 : #t257;
   core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double* #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       'x'] /*@ target=double::+ */ += getInt();
                                    ^" in #t260.{self::Test::[]}(#t261).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t264 = #t260.{self::Test::[]=}(#t261, #t262) in #t262;
   core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double* #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:214:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       'x'] /*@ target=double::+ */ += getNum();
                                    ^" in #t265.{self::Test::[]}(#t266).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t269 = #t265.{self::Test::[]=}(#t266, #t267) in #t267;
   core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double* #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:217:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       /*@ target=double::+ */ ++t
                               ^" in #t270.{self::Test::[]}(#t271).{core::double::+}(1) as{TypeError} core::int* in let final void #t274 = #t270.{self::Test::[]=}(#t271, #t272) in #t272;
   core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:221:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
       'x'] /*@ target=double::+ */ ++;
                                    ^" in #t277.{core::double::+}(1) as{TypeError} core::int*) in #t277;
 }
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
index 9749d80..e4b1a05 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
@@ -4,25 +4,21 @@
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:39: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 // var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
 //                                       ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:39: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 // var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
 //                                       ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:45: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //         /*@ type=int* */ /*@ target=A::+ */ ++);
 //                                             ^
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:48: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //         /*@ type=double* */ /*@ target=A::- */ --);
 //                                                ^
 //
@@ -46,22 +42,18 @@
 }
 static field core::int* v_prefix_pp = let final self::B* #t1 = new self::B::•() in #t1.{self::B::a} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:39: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
 var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
                                       ^" in #t1.{self::B::a}.{self::A::+}(1) as{TypeError} self::A*;
 static field core::double* v_prefix_mm = let final self::B* #t3 = new self::B::•() in #t3.{self::B::a} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:39: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
 var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
                                       ^" in #t3.{self::B::a}.{self::A::-}(1) as{TypeError} self::A*;
 static field self::A* v_postfix_pp = let final self::B* #t5 = new self::B::•() in let final self::A* #t6 = #t5.{self::B::a} in let final core::int* #t7 = #t5.{self::B::a} = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:45: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
         /*@ type=int* */ /*@ target=A::+ */ ++);
                                             ^" in #t6.{self::A::+}(1) as{TypeError} self::A* in #t6;
 static field self::A* v_postfix_mm = let final self::B* #t9 = new self::B::•() in let final self::A* #t10 = #t9.{self::B::a} in let final core::double* #t11 = #t9.{self::B::a} = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:48: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'A'.
         /*@ type=double* */ /*@ target=A::- */ --);
                                                ^" in #t10.{self::A::-}(1) as{TypeError} self::A* in #t10;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect
index 97a4e94..ce63906 100644
--- a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart:9:13: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
 // var x = i = s;
 //             ^
 //
@@ -13,7 +12,6 @@
 static field core::int* i;
 static field core::String* s;
 static field core::String* x = self::i = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart:9:13: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
 var x = i = s;
             ^" in self::s as{TypeError} core::int*;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
index 30f7d49..3579c0d 100644
--- a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
@@ -17,7 +17,7 @@
   ;
 static method bar() → () → void
   ;
-static method baz() → () → void
+static method baz() → () →? void
   ;
 static method hest() → () → void
   ;
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
index 71aef3b..588caa0 100644
--- a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
@@ -18,7 +18,7 @@
 static method foo() → void {}
 static method bar() → () → void
   return #C1;
-static method baz() → () → void
+static method baz() → () →? void
   return #C1;
 static method hest() → () → void
   return #C1;
@@ -30,7 +30,7 @@
   () → void g;
   () →? void f = g;
   () → void fBar = self::bar();
-  () → void fBaz = self::baz();
+  () →? void fBaz = self::baz();
   () → void fHest = self::hest();
   () →? void fFisk = self::fisk();
 }
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
index 71aef3b..588caa0 100644
--- a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
@@ -18,7 +18,7 @@
 static method foo() → void {}
 static method bar() → () → void
   return #C1;
-static method baz() → () → void
+static method baz() → () →? void
   return #C1;
 static method hest() → () → void
   return #C1;
@@ -30,7 +30,7 @@
   () → void g;
   () →? void f = g;
   () → void fBar = self::bar();
-  () → void fBaz = self::baz();
+  () →? void fBaz = self::baz();
   () → void fHest = self::hest();
   () →? void fFisk = self::fisk();
 }
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart b/pkg/front_end/testcases/nnbd/intersection_types.dart
new file mode 100644
index 0000000..d33b476
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The test checks the computation of the nullabilities of intersection types.
+
+class A {}
+class B extends A {}
+class C extends B {}
+
+class Foo<T extends A?> {
+  doPromotionsToNullable(T t) {
+    if (t is B?) {
+      var bar = t;
+      if (t is C?) {
+        var baz = t;
+      }
+    }
+  }
+
+  doPromotionsToNonNullable(T t) {
+    if (t is B) {
+      var bar = t;
+      if (t is C) {
+        var baz = t;
+      }
+    }
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect
new file mode 100644
index 0000000..26de83e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect
@@ -0,0 +1,26 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C*
+    ;
+}
+class Foo<T extends self::A? = self::A?> extends core::Object {
+  synthetic constructor •() → self::Foo<self::Foo::T*>*
+    ;
+  method doPromotionsToNullable(generic-covariant-impl self::Foo::T% t) → dynamic
+    ;
+  method doPromotionsToNonNullable(generic-covariant-impl self::Foo::T% t) → dynamic
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect
new file mode 100644
index 0000000..a65870d3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C*
+    : super self::B::•()
+    ;
+}
+class Foo<T extends self::A? = self::A?> extends core::Object {
+  synthetic constructor •() → self::Foo<self::Foo::T*>*
+    : super core::Object::•()
+    ;
+  method doPromotionsToNullable(generic-covariant-impl self::Foo::T% t) → dynamic {
+    if(t is self::B?) {
+      self::Foo::T% & self::B? /* '%' & '?' = '%' */ bar = t{self::Foo::T% & self::B? /* '%' & '?' = '%' */};
+      if(t{self::Foo::T% & self::B? /* '%' & '?' = '%' */} is self::C?) {
+        self::Foo::T% & self::C? /* '%' & '?' = '%' */ baz = t{self::Foo::T% & self::C? /* '%' & '?' = '%' */};
+      }
+    }
+  }
+  method doPromotionsToNonNullable(generic-covariant-impl self::Foo::T% t) → dynamic {
+    if(t is self::B) {
+      self::Foo::T% & self::B /* '%' & '!' = '!' */ bar = t{self::Foo::T% & self::B /* '%' & '!' = '!' */};
+      if(t{self::Foo::T% & self::B /* '%' & '!' = '!' */} is self::C) {
+        self::Foo::T & self::C /* '!' & '!' = '!' */ baz = t{self::Foo::T & self::C /* '!' & '!' = '!' */};
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..a65870d3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C*
+    : super self::B::•()
+    ;
+}
+class Foo<T extends self::A? = self::A?> extends core::Object {
+  synthetic constructor •() → self::Foo<self::Foo::T*>*
+    : super core::Object::•()
+    ;
+  method doPromotionsToNullable(generic-covariant-impl self::Foo::T% t) → dynamic {
+    if(t is self::B?) {
+      self::Foo::T% & self::B? /* '%' & '?' = '%' */ bar = t{self::Foo::T% & self::B? /* '%' & '?' = '%' */};
+      if(t{self::Foo::T% & self::B? /* '%' & '?' = '%' */} is self::C?) {
+        self::Foo::T% & self::C? /* '%' & '?' = '%' */ baz = t{self::Foo::T% & self::C? /* '%' & '?' = '%' */};
+      }
+    }
+  }
+  method doPromotionsToNonNullable(generic-covariant-impl self::Foo::T% t) → dynamic {
+    if(t is self::B) {
+      self::Foo::T% & self::B /* '%' & '!' = '!' */ bar = t{self::Foo::T% & self::B /* '%' & '!' = '!' */};
+      if(t{self::Foo::T% & self::B /* '%' & '!' = '!' */} is self::C) {
+        self::Foo::T & self::C /* '!' & '!' = '!' */ baz = t{self::Foo::T & self::C /* '!' & '!' = '!' */};
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.type_promotion.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.type_promotion.expect
new file mode 100644
index 0000000..ffa128e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.type_promotion.expect
@@ -0,0 +1,12 @@
+pkg/front_end/testcases/nnbd/intersection_types.dart:13:11: Context: Possible promotion of t@403
+    if (t is B?) {
+          ^^
+pkg/front_end/testcases/nnbd/intersection_types.dart:15:13: Context: Possible promotion of t@403
+      if (t is C?) {
+            ^^
+pkg/front_end/testcases/nnbd/intersection_types.dart:22:11: Context: Possible promotion of t@403
+    if (t is B) {
+          ^^
+pkg/front_end/testcases/nnbd/intersection_types.dart:24:13: Context: Possible promotion of t@403
+      if (t is C) {
+            ^^
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart
new file mode 100644
index 0000000..eefd595
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The test checks the nullability of the result of the type substitution
+// performed as a part of type inference, including its fall-back mechanism
+// which is instantiate-to-bounds.
+
+foo<T extends Object?, S extends List<T>>(T t) => null;
+
+bar<T extends Object?, S extends List<T?>>(T t) => null;
+
+baz(int? x, int y) {
+  foo(x);
+  bar(y);
+}
+
+class A<T extends Object?, S extends Object> {
+  hest<X extends T, Y extends List<X>, Z extends List<X?>>() => null;
+  fisk<X extends S, Y extends List<X>, Z extends List<X?>>() => null;
+  mus<X extends Object?, Y extends List<X>, Z extends List<X?>>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect
new file mode 100644
index 0000000..5c95be5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = core::Object?, S extends core::Object = core::Object> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T*, self::A::S*>*
+    ;
+  method hest<generic-covariant-impl X extends self::A::T% = self::A::T%, Y extends core::List<self::A::hest::X%> = core::List<self::A::T%>, Z extends core::List<self::A::hest::X?> = core::List<self::A::T?>>() → dynamic
+    ;
+  method fisk<generic-covariant-impl X extends self::A::S = self::A::S, Y extends core::List<self::A::fisk::X> = core::List<self::A::S>, Z extends core::List<self::A::fisk::X?> = core::List<self::A::S?>>() → dynamic
+    ;
+  method mus<X extends core::Object? = core::Object?, Y extends core::List<self::A::mus::X%> = core::List<core::Object?>, Z extends core::List<self::A::mus::X?> = core::List<core::Object?>>() → dynamic
+    ;
+}
+static method foo<T extends core::Object? = core::Object?, S extends core::List<self::foo::T%> = core::List<core::Object?>>(self::foo::T% t) → dynamic
+  ;
+static method bar<T extends core::Object? = core::Object?, S extends core::List<self::bar::T?> = core::List<core::Object?>>(self::bar::T% t) → dynamic
+  ;
+static method baz(core::int? x, core::int y) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect
new file mode 100644
index 0000000..ed9375c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = core::Object?, S extends core::Object = core::Object> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T*, self::A::S*>*
+    : super core::Object::•()
+    ;
+  method hest<generic-covariant-impl X extends self::A::T% = self::A::T%, Y extends core::List<self::A::hest::X%> = core::List<self::A::T%>, Z extends core::List<self::A::hest::X?> = core::List<self::A::T?>>() → dynamic
+    return null;
+  method fisk<generic-covariant-impl X extends self::A::S = self::A::S, Y extends core::List<self::A::fisk::X> = core::List<self::A::S>, Z extends core::List<self::A::fisk::X?> = core::List<self::A::S?>>() → dynamic
+    return null;
+  method mus<X extends core::Object? = core::Object?, Y extends core::List<self::A::mus::X%> = core::List<core::Object?>, Z extends core::List<self::A::mus::X?> = core::List<core::Object?>>() → dynamic
+    return null;
+}
+static method foo<T extends core::Object? = core::Object?, S extends core::List<self::foo::T%> = core::List<core::Object?>>(self::foo::T% t) → dynamic
+  return null;
+static method bar<T extends core::Object? = core::Object?, S extends core::List<self::bar::T?> = core::List<core::Object?>>(self::bar::T% t) → dynamic
+  return null;
+static method baz(core::int? x, core::int y) → dynamic {
+  self::foo<core::int?, core::List<core::int?>>(x);
+  self::bar<core::int, core::List<core::int?>>(y);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..ed9375c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = core::Object?, S extends core::Object = core::Object> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T*, self::A::S*>*
+    : super core::Object::•()
+    ;
+  method hest<generic-covariant-impl X extends self::A::T% = self::A::T%, Y extends core::List<self::A::hest::X%> = core::List<self::A::T%>, Z extends core::List<self::A::hest::X?> = core::List<self::A::T?>>() → dynamic
+    return null;
+  method fisk<generic-covariant-impl X extends self::A::S = self::A::S, Y extends core::List<self::A::fisk::X> = core::List<self::A::S>, Z extends core::List<self::A::fisk::X?> = core::List<self::A::S?>>() → dynamic
+    return null;
+  method mus<X extends core::Object? = core::Object?, Y extends core::List<self::A::mus::X%> = core::List<core::Object?>, Z extends core::List<self::A::mus::X?> = core::List<core::Object?>>() → dynamic
+    return null;
+}
+static method foo<T extends core::Object? = core::Object?, S extends core::List<self::foo::T%> = core::List<core::Object?>>(self::foo::T% t) → dynamic
+  return null;
+static method bar<T extends core::Object? = core::Object?, S extends core::List<self::bar::T?> = core::List<core::Object?>>(self::bar::T% t) → dynamic
+  return null;
+static method baz(core::int? x, core::int y) → dynamic {
+  self::foo<core::int?, core::List<core::int?>>(x);
+  self::bar<core::int, core::List<core::int?>>(y);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect
index fc08a34..b1d19a9 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
+// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in its declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
 //   B() : super.a = 42;
 //               ^
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect
index 38d2b3a..6ae43db 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
+// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in its declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
 //   B() : super.a = 42;
 //               ^
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect
index 38d2b3a..6ae43db 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
+// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in its declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
 //   B() : super.a = 42;
 //               ^
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart b/pkg/front_end/testcases/regress/issue_37681.dart
new file mode 100644
index 0000000..ca0cd8b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() async {
+  int f_async() async { return 42; }
+  print(await f_async());
+
+  int f_async_star() async* { yield 42; }
+  await for (var x in f_async_star() as dynamic) {
+    print(x);
+  }
+
+  int f_sync_star() sync* { yield 42; }
+  for (var x in f_sync_star() as dynamic) {
+    print(x);
+  }
+}
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.outline.expect b/pkg/front_end/testcases/regress/issue_37681.dart.outline.expect
new file mode 100644
index 0000000..6a28c0d
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.outline.expect
@@ -0,0 +1,5 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.strong.expect b/pkg/front_end/testcases/regress/issue_37681.dart.strong.expect
new file mode 100644
index 0000000..3166bc2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.strong.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37681.dart:6:7: Error: Functions marked 'async' must have a return type assignable to 'Future'.
+//   int f_async() async { return 42; }
+//       ^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_37681.dart:9:7: Error: Functions marked 'async*' must have a return type assignable to 'Stream'.
+//   int f_async_star() async* { yield 42; }
+//       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_37681.dart:14:7: Error: Functions marked 'sync*' must have a return type assignable to 'Iterable'.
+//   int f_sync_star() sync* { yield 42; }
+//       ^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method main() → dynamic async {
+  function f_async() → core::int* async {
+    return 42;
+  }
+  core::print(await f_async.call());
+  function f_async_star() → core::int* async* {
+    yield 42;
+  }
+  await for (dynamic x in (f_async_star.call() as dynamic) as{TypeError} asy::Stream<dynamic>*) {
+    core::print(x);
+  }
+  function f_sync_star() → core::int* sync* {
+    yield 42;
+  }
+  for (dynamic x in (f_sync_star.call() as dynamic) as{TypeError} core::Iterable<dynamic>*) {
+    core::print(x);
+  }
+}
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
new file mode 100644
index 0000000..5cffed8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
@@ -0,0 +1,154 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37681.dart:6:7: Error: Functions marked 'async' must have a return type assignable to 'Future'.
+//   int f_async() async { return 42; }
+//       ^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_37681.dart:9:7: Error: Functions marked 'async*' must have a return type assignable to 'Stream'.
+//   int f_async_star() async* { yield 42; }
+//       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_37681.dart:14:7: Error: Functions marked 'sync*' must have a return type assignable to 'Iterable'.
+//   int f_sync_star() sync* { yield 42; }
+//       ^^^^^^^^^^^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  asy::FutureOr<dynamic>* :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        function f_async() → core::int* /* originally async */ {
+          final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          asy::FutureOr<dynamic>* :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L2:
+              {
+                :return_value = 42;
+                break #L2;
+              }
+              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :async_completer.start(:async_op);
+          return :async_completer.{asy::Completer::future};
+        }
+        [yield] let dynamic #t1 = asy::_awaitHelper(f_async.call(), :async_op_then, :async_op_error, :async_op) in null;
+        core::print(:result);
+        function f_async_star() → core::int* /* originally async* */ {
+          asy::_AsyncStarStreamController<dynamic>* :controller;
+          dynamic :controller_stream;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L3:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(42))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+          :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+          return :controller_stream;
+        }
+        {
+          dynamic :stream = (f_async_star.call() as dynamic) as{TypeError} asy::Stream<dynamic>*;
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<dynamic>* :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
+          try
+            #L4:
+            while (true) {
+              dynamic #t2 = asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::print(x);
+                }
+              }
+              else
+                break #L4;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        function f_sync_star() → core::int* /* originally sync* */ {
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :sync_op(core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+            {
+              {
+                :iterator.{core::_SyncIterator::_current} = 42;
+                [yield] true;
+              }
+            }
+            return false;
+          }
+          return new core::_SyncIterable::•<dynamic>(:sync_op);
+        }
+        for (dynamic x in (f_sync_star.call() as dynamic) as{TypeError} core::Iterable<dynamic>*) {
+          core::print(x);
+        }
+      }
+      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :async_completer.start(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
index d90577e..e262b07 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: The argument type 'double' can't be assigned to the parameter type 'U'.
-// Try changing the type of the parameter, or casting the argument to 'U'.
 //     this.f<U>(1.5);
 //               ^
 //
@@ -23,7 +22,6 @@
   method f<generic-covariant-impl U extends self::C::T* = self::C::T*>(self::C::f::U* x) → void {}
   method g1<generic-covariant-impl U extends self::C::T* = self::C::T*>() → void {
     this.{self::C::f}<self::C::g1::U*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: The argument type 'double' can't be assigned to the parameter type 'U'.
-Try changing the type of the parameter, or casting the argument to 'U'.
     this.f<U>(1.5);
               ^" in 1.5 as{TypeError} <BottomType>);
   }
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
index d90577e..e262b07 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -3,7 +3,6 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: The argument type 'double' can't be assigned to the parameter type 'U'.
-// Try changing the type of the parameter, or casting the argument to 'U'.
 //     this.f<U>(1.5);
 //               ^
 //
@@ -23,7 +22,6 @@
   method f<generic-covariant-impl U extends self::C::T* = self::C::T*>(self::C::f::U* x) → void {}
   method g1<generic-covariant-impl U extends self::C::T* = self::C::T*>() → void {
     this.{self::C::f}<self::C::g1::U*>(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: The argument type 'double' can't be assigned to the parameter type 'U'.
-Try changing the type of the parameter, or casting the argument to 'U'.
     this.f<U>(1.5);
               ^" in 1.5 as{TypeError} <BottomType>);
   }
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
index 8d3508c..1a716ef 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:49:46: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //   d.value /*@ checkReturn=(num*) ->* num* */ += 1;
 //                                              ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:48: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //     d.value /*@ checkReturn=(num*) ->* num* */ += 1;
 //                                                ^
 //
@@ -55,14 +53,12 @@
 static method main() → void {
   self::D* d = new self::D::•(new self::C::•<core::num*>(#C1));
   let final self::D* #t1 = d in #t1.{self::D::value} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:49:46: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
   d.value /*@ checkReturn=(num*) ->* num* */ += 1;
                                              ^" in (#t1.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num*) →* core::num*) as{TypeError} (core::int*) →* core::int*;
   self::expect(d.{self::D::setValue}(0), 1);
   d = new self::D::•(new self::C::•<core::num*>(#C2));
   self::expectTypeError(() → core::Null? {
     let final self::D* #t3 = d in #t3.{self::D::value} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:48: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
     d.value /*@ checkReturn=(num*) ->* num* */ += 1;
                                                ^" in (#t3.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num*) →* core::num*) as{TypeError} (core::int*) →* core::int*;
   });
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
index 8d3508c..1a716ef 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
@@ -3,12 +3,10 @@
 // Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:49:46: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //   d.value /*@ checkReturn=(num*) ->* num* */ += 1;
 //                                              ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:48: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //     d.value /*@ checkReturn=(num*) ->* num* */ += 1;
 //                                                ^
 //
@@ -55,14 +53,12 @@
 static method main() → void {
   self::D* d = new self::D::•(new self::C::•<core::num*>(#C1));
   let final self::D* #t1 = d in #t1.{self::D::value} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:49:46: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
   d.value /*@ checkReturn=(num*) ->* num* */ += 1;
                                              ^" in (#t1.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num*) →* core::num*) as{TypeError} (core::int*) →* core::int*;
   self::expect(d.{self::D::setValue}(0), 1);
   d = new self::D::•(new self::C::•<core::num*>(#C2));
   self::expectTypeError(() → core::Null? {
     let final self::D* #t3 = d in #t3.{self::D::value} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:48: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
-Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
     d.value /*@ checkReturn=(num*) ->* num* */ += 1;
                                                ^" in (#t3.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num*) →* core::num*) as{TypeError} (core::int*) →* core::int*;
   });
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
index 26a02ad..d3b1e07 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
@@ -4,25 +4,21 @@
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
 //   c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
 //                                                      ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
 //   var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
 //                                                              ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:55: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
 //   c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
 //                                                       ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:63: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
 //   var z = c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
 //                                                               ^
 //
@@ -48,22 +44,18 @@
 static method test(self::C<core::num*>* c) → void {
   let final self::C<core::num*>* #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
   c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
                                                      ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
   self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
   var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
                                                              ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
   let final self::C<core::num*>* #t5 = c in (#t5.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<core::Object*>*} #t5.{self::C::x} = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:55: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
   c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
                                                       ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>* : null;
   self::B<core::Object*>* z = let final self::C<core::num*>* #t7 = c in let final self::B<(core::num*) →* void>* #t8 = #t7.{self::C::x} as{TypeError} self::B<(core::num*) →* void>* in #t8.{core::Object::==}(null) ?{self::B<core::Object*>*} #t7.{self::C::x} = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:63: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
   var z = c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
                                                               ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>* : #t8;
 }
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
index 26a02ad..d3b1e07 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
@@ -4,25 +4,21 @@
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
 //   c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
 //                                                      ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
 //   var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
 //                                                              ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:55: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
 //   c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
 //                                                       ^
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:63: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
 //   var z = c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
 //                                                               ^
 //
@@ -48,22 +44,18 @@
 static method test(self::C<core::num*>* c) → void {
   let final self::C<core::num*>* #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
   c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
                                                      ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
   self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
   var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
                                                              ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
   let final self::C<core::num*>* #t5 = c in (#t5.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<core::Object*>*} #t5.{self::C::x} = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:55: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
   c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
                                                       ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>* : null;
   self::B<core::Object*>* z = let final self::C<core::num*>* #t7 = c in let final self::B<(core::num*) →* void>* #t8 = #t7.{self::C::x} as{TypeError} self::B<(core::num*) →* void>* in #t8.{core::Object::==}(null) ?{self::B<core::Object*>*} #t7.{self::C::x} = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:63: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
   var z = c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
                                                               ^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>* : #t8;
 }
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
index 7a16814..486d1399 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
@@ -34,7 +34,6 @@
 //  - 'Set' is from 'dart:core'.
 //  - 'FutureOr' is from 'dart:async'.
 //  - 'LinkedHashSet' is from 'dart:collection'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
 // FutureOr<LinkedHashSet<int>> lhsfun2() => {};
 //                                           ^
 //
@@ -42,7 +41,6 @@
 //  - 'Map' is from 'dart:core'.
 //  - 'FutureOr' is from 'dart:async'.
 //  - 'LinkedHashMap' is from 'dart:collection'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashMap<int, bool>>'.
 // FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
 //                                                 ^
 //
@@ -112,7 +110,6 @@
  - 'Set' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashSet' is from 'dart:collection'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
 FutureOr<LinkedHashSet<int>> lhsfun2() => {};
                                           ^" in (let final core::Set<dynamic>* #t14 = col::LinkedHashSet::•<dynamic>() in #t14) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int*>*>*;
 static method lhmfun2() → asy::FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>*
@@ -120,6 +117,5 @@
  - 'Map' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashMap' is from 'dart:collection'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashMap<int, bool>>'.
 FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
                                                 ^" in <dynamic, dynamic>{} as{TypeError} asy::FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>*;
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
index 2dce7db..5af0f46 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
@@ -34,7 +34,6 @@
 //  - 'Set' is from 'dart:core'.
 //  - 'FutureOr' is from 'dart:async'.
 //  - 'LinkedHashSet' is from 'dart:collection'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
 // FutureOr<LinkedHashSet<int>> lhsfun2() => {};
 //                                           ^
 //
@@ -42,7 +41,6 @@
 //  - 'Map' is from 'dart:core'.
 //  - 'FutureOr' is from 'dart:async'.
 //  - 'LinkedHashMap' is from 'dart:collection'.
-// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashMap<int, bool>>'.
 // FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
 //                                                 ^
 //
@@ -271,7 +269,6 @@
  - 'Set' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashSet' is from 'dart:collection'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
 FutureOr<LinkedHashSet<int>> lhsfun2() => {};
                                           ^" in (let final core::Set<dynamic>* #t24 = col::LinkedHashSet::•<dynamic>() in #t24) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int*>*>*;
 static method lhmfun2() → asy::FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>*
@@ -279,6 +276,5 @@
  - 'Map' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashMap' is from 'dart:collection'.
-Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashMap<int, bool>>'.
 FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
                                                 ^" in <dynamic, dynamic>{} as{TypeError} asy::FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>*;
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 6bafcf8..bed5b80 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -12,6 +12,7 @@
 extensions/annotations: TextSerializationFailure
 extensions/check_bounds: TextSerializationFailure
 extensions/compounds: TextSerializationFailure
+extensions/conflict_with_object: TextSerializationFailure
 extensions/conflicts: TextSerializationFailure
 extensions/default_values: TextSerializationFailure
 extensions/direct_instance_access: TextSerializationFailure
@@ -27,17 +28,19 @@
 extensions/extension_methods: TextSerializationFailure
 extensions/extension_setter: TextSerializationFailure
 extensions/extension_setter_error: TypeCheckError
+extensions/generic_function_in_generic_extension: TextSerializationFailure
 extensions/getter_setter_conflict: TextSerializationFailure
 extensions/if_null: TextSerializationFailure
 extensions/implicit_extension_inference: TextSerializationFailure
 extensions/implicit_this: TextSerializationFailure
 extensions/index: TextSerializationFailure
-extensions/internal_resolution: TextSerializationFailure
 extensions/instance_access: TextSerializationFailure
 extensions/instance_access_of_static: TextSerializationFailure
 extensions/instance_members: TextSerializationFailure
 extensions/instance_tearoff: TextSerializationFailure
+extensions/internal_resolution: TextSerializationFailure
 extensions/invalid_explicit_access: TextSerializationFailure
+extensions/invalid_explicit_static_access: TextSerializationFailure
 extensions/nested_on_types: TextSerializationFailure
 extensions/null_aware: TextSerializationFailure
 extensions/on_function_type: TextSerializationFailure
@@ -158,6 +161,7 @@
 general/function_type_recovery: TextSerializationFailure # Was: Pass
 general/functions: TextSerializationFailure # Was: Pass
 general/future_or_test: TextSerializationFailure # Was: Pass
+general/generic_function_type_in_message: TextSerializationFailure
 general/having_part_with_part_and_annotation: TextSerializationFailure
 general/having_part_with_parts_and_annotation: TextSerializationFailure
 general/hello: TextSerializationFailure # Was: Pass
@@ -857,10 +861,12 @@
 nested_variance_test: TextSerializationFailure
 new_const_insertion/simple: TextSerializationFailure # Was: Pass
 nnbd/function_types: TextSerializationFailure
+nnbd/intersection_types: TextSerializationFailure
 nnbd/late: TextSerializationFailure
 nnbd/null_check: TextSerializationFailure
 nnbd/nullable_param: TextSerializationFailure
 nnbd/required: TextSerializationFailure
+nnbd/substitution_in_inference: TextSerializationFailure
 nnbd/type_parameter_types: TextSerializationFailure
 no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
 no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
@@ -1045,6 +1051,7 @@
 regress/issue_36669: TextSerializationFailure
 regress/issue_36793: TextSerializationFailure
 regress/issue_37285: TextSerializationFailure
+regress/issue_37681: TextSerializationFailure
 runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
 runtime_checks/call_kinds_get: TextSerializationFailure # Was: Pass
 runtime_checks/call_kinds_set: TextSerializationFailure # Was: Pass
@@ -1118,6 +1125,6 @@
 runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass
 runtime_checks_new/stub_from_interface_covariant_from_super: TextSerializationFailure # Was: Pass
 set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError
+top_level_variance_test: TextSerializationFailure
 variance/class_type_parameter_modifier: TextSerializationFailure
 variance/mixin_type_parameter_modifier: TextSerializationFailure
-top_level_variance_test: TextSerializationFailure
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index d8a353e..333a741 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -353,7 +353,7 @@
 type ExtensionMemberDescriptor {
   StringReference name;
   ExtensionMemberKind kind;
-  Byte flags (isStatic, isExternal);
+  Byte flags (isStatic);
   MemberReference member;
 }
 
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index cd777e3..49f81a9 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1350,7 +1350,6 @@
 /// Information about an member declaration in an extension.
 class ExtensionMemberDescriptor {
   static const int FlagStatic = 1 << 0; // Must match serialized bit positions.
-  static const int FlagExternal = 1 << 1;
 
   /// The name of the extension member.
   ///
@@ -1387,28 +1386,16 @@
   Reference member;
 
   ExtensionMemberDescriptor(
-      {this.name,
-      this.kind,
-      bool isStatic: false,
-      bool isExternal: false,
-      this.member}) {
+      {this.name, this.kind, bool isStatic: false, this.member}) {
     this.isStatic = isStatic;
-    this.isExternal = isExternal;
   }
 
   /// Return `true` if the extension method was declared as `static`.
   bool get isStatic => flags & FlagStatic != 0;
 
-  /// Return `true` if the extension method was declared as `external`.
-  bool get isExternal => flags & FlagExternal != 0;
-
   void set isStatic(bool value) {
     flags = value ? (flags | FlagStatic) : (flags & ~FlagStatic);
   }
-
-  void set isExternal(bool value) {
-    flags = value ? (flags | FlagExternal) : (flags & ~FlagExternal);
-  }
 }
 
 // ------------------------------------------------------------------------
@@ -5411,6 +5398,12 @@
   /// If this is a typedef type, unfolds its type definition once, otherwise
   /// returns the type itself.
   DartType get unaliasOnce => this;
+
+  /// Creates a copy of the type with the given [nullability] if possible.
+  ///
+  /// Some types have fixed nullabilities, such as `dynamic`, `invalid-type`,
+  /// `void`, or `bottom`.
+  DartType withNullability(Nullability nullability);
 }
 
 /// The type arising from invalid type annotations.
@@ -5430,6 +5423,8 @@
   bool operator ==(Object other) => other is InvalidType;
 
   Nullability get nullability => throw "InvalidType doesn't have nullability";
+
+  InvalidType withNullability(Nullability nullability) => this;
 }
 
 class DynamicType extends DartType {
@@ -5445,6 +5440,8 @@
   bool operator ==(Object other) => other is DynamicType;
 
   Nullability get nullability => Nullability.nullable;
+
+  DynamicType withNullability(Nullability nullability) => this;
 }
 
 class VoidType extends DartType {
@@ -5460,6 +5457,8 @@
   bool operator ==(Object other) => other is VoidType;
 
   Nullability get nullability => Nullability.nullable;
+
+  VoidType withNullability(Nullability nullability) => this;
 }
 
 class BottomType extends DartType {
@@ -5475,6 +5474,8 @@
   bool operator ==(Object other) => other is BottomType;
 
   Nullability get nullability => Nullability.nonNullable;
+
+  BottomType withNullability(Nullability nullability) => this;
 }
 
 class InterfaceType extends DartType {
@@ -5537,6 +5538,12 @@
     }
     return hash;
   }
+
+  InterfaceType withNullability(Nullability nullability) {
+    return nullability == this.nullability
+        ? this
+        : new InterfaceType.byReference(className, typeArguments, nullability);
+  }
 }
 
 /// A possibly generic function type.
@@ -5668,6 +5675,18 @@
     }
     return hash;
   }
+
+  FunctionType withNullability(Nullability nullability) {
+    if (nullability == this.nullability) return this;
+    FunctionType result = FunctionType(positionalParameters, returnType,
+        namedParameters: namedParameters,
+        typeParameters: typeParameters,
+        nullability: nullability,
+        requiredParameterCount: requiredParameterCount,
+        typedefType: typedefType?.withNullability(nullability));
+    if (typeParameters.isEmpty) return result;
+    return getFreshTypeParameters(typeParameters).applyToFunctionType(result);
+  }
 }
 
 /// A use of a [Typedef] as a type.
@@ -5699,7 +5718,9 @@
   }
 
   DartType get unaliasOnce {
-    return Substitution.fromTypedefType(this).substituteType(typedefNode.type);
+    return Substitution.fromTypedefType(this)
+        .substituteType(typedefNode.type)
+        .withNullability(nullability);
   }
 
   DartType get unalias {
@@ -5728,6 +5749,13 @@
     }
     return hash;
   }
+
+  TypedefType withNullability(Nullability nullability) {
+    return nullability == this.nullability
+        ? this
+        : new TypedefType.byReference(
+            typedefReference, typeArguments, nullability);
+  }
 }
 
 /// A named parameter in [FunctionType].
@@ -5842,6 +5870,19 @@
         promotedBound);
   }
 
+  /// Gets a new [TypeParameterType] with given [typeParameterTypeNullability].
+  ///
+  /// In contrast with other types, [TypeParameterType.withNullability] doesn't
+  /// set the overall nullability of the returned type but sets that of the
+  /// left-hand side of the intersection type.  In case [promotedBound] is null,
+  /// it is an equivalent of setting the overall nullability.
+  TypeParameterType withNullability(Nullability typeParameterTypeNullability) {
+    return typeParameterTypeNullability == this.typeParameterTypeNullability
+        ? this
+        : new TypeParameterType(
+            parameter, promotedBound, typeParameterTypeNullability);
+  }
+
   /// Gets the nullability of a type-parameter type based on the bound.
   ///
   /// This is a helper function to be used when the bound of the type parameter
@@ -6731,9 +6772,12 @@
   /// or referenced from the metadata payload.
   ///
   /// Currently due to binary format specifics Catch and MapEntry nodes
-  /// can't have metadata attached to them.
+  /// can't have metadata attached to them. Also, metadata is not saved on
+  /// Block nodes inside BlockExpressions.
   static bool isSupported(TreeNode node) {
-    return !(node is MapEntry || node is Catch);
+    return !(node is MapEntry ||
+        node is Catch ||
+        (node is Block && node.parent is BlockExpression));
   }
 }
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index f717ce2..4ef7288 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -5,6 +5,7 @@
 
 import 'dart:core' hide MapEntry;
 import 'dart:convert';
+import 'dart:developer';
 import 'dart:typed_data';
 
 import '../ast.dart';
@@ -454,34 +455,36 @@
   ///
   /// The input bytes may contain multiple files concatenated.
   void readComponent(Component component, {bool checkCanonicalNames: false}) {
-    _checkEmptyInput();
+    Timeline.timeSync("BinaryBuilder.readComponent", () {
+      _checkEmptyInput();
 
-    // Check that we have a .dill file and it has the correct version before we
-    // start decoding it.  Otherwise we will fail for cryptic reasons.
-    int offset = _byteOffset;
-    int magic = readUint32();
-    if (magic != Tag.ComponentFile) {
-      throw ArgumentError('Not a .dill file (wrong magic number).');
-    }
-    int version = readUint32();
-    if (version != Tag.BinaryFormatVersion) {
-      throw InvalidKernelVersionError(version);
-    }
-    _byteOffset = offset;
-    List<int> componentFileSizes = _indexComponents();
-    if (componentFileSizes.length > 1) {
-      _disableLazyReading = true;
-      _disableLazyClassReading = true;
-    }
-    int componentFileIndex = 0;
-    while (_byteOffset < _bytes.length) {
-      _readOneComponent(component, componentFileSizes[componentFileIndex]);
-      ++componentFileIndex;
-    }
+      // Check that we have a .dill file and it has the correct version before we
+      // start decoding it.  Otherwise we will fail for cryptic reasons.
+      int offset = _byteOffset;
+      int magic = readUint32();
+      if (magic != Tag.ComponentFile) {
+        throw ArgumentError('Not a .dill file (wrong magic number).');
+      }
+      int version = readUint32();
+      if (version != Tag.BinaryFormatVersion) {
+        throw InvalidKernelVersionError(version);
+      }
+      _byteOffset = offset;
+      List<int> componentFileSizes = _indexComponents();
+      if (componentFileSizes.length > 1) {
+        _disableLazyReading = true;
+        _disableLazyClassReading = true;
+      }
+      int componentFileIndex = 0;
+      while (_byteOffset < _bytes.length) {
+        _readOneComponent(component, componentFileSizes[componentFileIndex]);
+        ++componentFileIndex;
+      }
 
-    if (checkCanonicalNames) {
-      _checkCanonicalNameChildren(component.root);
-    }
+      if (checkCanonicalNames) {
+        _checkCanonicalNameChildren(component.root);
+      }
+    });
   }
 
   /// Deserializes the source and stores it in [component].
@@ -2266,8 +2269,16 @@
   /// and are awaiting to be parsed and attached to nodes.
   List<_MetadataSubsection> _subsections;
 
-  BinaryBuilderWithMetadata(bytes, [filename])
-      : super(bytes, filename: filename);
+  BinaryBuilderWithMetadata(List<int> bytes,
+      {String filename,
+      bool disableLazyReading = false,
+      bool disableLazyClassReading = false,
+      bool alwaysCreateNewNamedNodes})
+      : super(bytes,
+            filename: filename,
+            disableLazyReading: disableLazyReading,
+            disableLazyClassReading: disableLazyClassReading,
+            alwaysCreateNewNamedNodes: alwaysCreateNewNamedNodes);
 
   @override
   void _readMetadataMappings(
@@ -2381,6 +2392,13 @@
   }
 
   @override
+  Extension readExtension() {
+    final nodeOffset = _byteOffset;
+    final result = super.readExtension();
+    return _associateMetadata(result, nodeOffset);
+  }
+
+  @override
   Field readField() {
     final nodeOffset = _byteOffset;
     final result = super.readField();
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 8abfe1b..babd66e 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -5,11 +5,12 @@
 
 import 'dart:core' hide MapEntry;
 import 'dart:convert' show utf8;
+import 'dart:developer';
+import 'dart:io' show BytesBuilder;
+import 'dart:typed_data';
 
 import '../ast.dart';
 import 'tag.dart';
-import 'dart:io' show BytesBuilder;
-import 'dart:typed_data';
 
 /// Writes to a binary file.
 ///
@@ -83,6 +84,7 @@
     _sink.addBytes(bytes);
   }
 
+  @pragma("vm:prefer-inline")
   void writeUInt30(int value) {
     assert(value >= 0 && value >> 30 == 0);
     if (value < 0x80) {
@@ -539,30 +541,32 @@
   }
 
   void writeComponentFile(Component component) {
-    computeCanonicalNames(component);
-    final componentOffset = getBufferOffset();
-    writeUInt32(Tag.ComponentFile);
-    writeUInt32(Tag.BinaryFormatVersion);
-    writeListOfStrings(component.problemsAsJson);
-    indexLinkTable(component);
-    _collectMetadata(component);
-    if (_metadataSubsections != null) {
-      _writeNodeMetadataImpl(component, componentOffset);
-    }
-    libraryOffsets = <int>[];
-    CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
-    if (main != null) {
-      checkCanonicalName(main);
-    }
-    writeLibraries(component);
-    writeUriToSource(component.uriToSource);
-    writeLinkTable(component);
-    _writeMetadataSection(component);
-    writeStringTable(stringIndexer);
-    writeConstantTable(_constantIndexer);
-    writeComponentIndex(component, component.libraries);
+    Timeline.timeSync("BinaryPrinter.writeComponentFile", () {
+      computeCanonicalNames(component);
+      final componentOffset = getBufferOffset();
+      writeUInt32(Tag.ComponentFile);
+      writeUInt32(Tag.BinaryFormatVersion);
+      writeListOfStrings(component.problemsAsJson);
+      indexLinkTable(component);
+      _collectMetadata(component);
+      if (_metadataSubsections != null) {
+        _writeNodeMetadataImpl(component, componentOffset);
+      }
+      libraryOffsets = <int>[];
+      CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
+      if (main != null) {
+        checkCanonicalName(main);
+      }
+      writeLibraries(component);
+      writeUriToSource(component.uriToSource);
+      writeLinkTable(component);
+      _writeMetadataSection(component);
+      writeStringTable(stringIndexer);
+      writeConstantTable(_constantIndexer);
+      writeComponentIndex(component, component.libraries);
 
-    _flush();
+      _flush();
+    });
   }
 
   void writeListOfStrings(List<String> strings) {
@@ -2605,6 +2609,7 @@
         _doubleBufferUint8[6], _doubleBufferUint8[7]);
   }
 
+  @pragma("vm:prefer-inline")
   void addByte(int byte) {
     _buffer[length++] = byte;
     if (length == SIZE) {
@@ -2615,6 +2620,7 @@
     }
   }
 
+  @pragma("vm:prefer-inline")
   void addByte2(int byte1, int byte2) {
     if (length < SAFE_SIZE) {
       _buffer[length++] = byte1;
@@ -2625,6 +2631,7 @@
     }
   }
 
+  @pragma("vm:prefer-inline")
   void addByte4(int byte1, int byte2, int byte3, int byte4) {
     if (length < SAFE_SIZE) {
       _buffer[length++] = byte1;
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index 0e31d92..27985e7 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -7,6 +7,7 @@
 import 'kernel.dart';
 import 'type_checker.dart' as type_checker;
 import 'type_algebra.dart';
+import 'type_environment.dart';
 
 abstract class FailureListener {
   void reportFailure(TreeNode node, String message);
@@ -90,7 +91,8 @@
       } else {
         final DartType ownType = getterType(host, ownMember);
         final DartType superType = getterType(host, superMember);
-        if (!environment.isSubtypeOf(ownType, superType)) {
+        if (!environment.isSubtypeOf(
+            ownType, superType, SubtypeCheckMode.ignoringNullabilities)) {
           return failures.reportInvalidOverride(ownMember, superMember, '''
 ${ownType} is not a subtype of ${superType}
 ''');
@@ -106,8 +108,8 @@
 
   /// Check if [subtype] is subtype of [supertype] after applying
   /// type parameter [substitution].
-  bool _isSubtypeOf(DartType subtype, DartType supertype) =>
-      environment.isSubtypeOf(subtype, supertype);
+  bool _isSubtypeOf(DartType subtype, DartType supertype) => environment
+      .isSubtypeOf(subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
 
   Substitution _makeSubstitutionForMember(Class host, Member member) {
     final hostType =
@@ -232,8 +234,10 @@
   void checkAssignable(TreeNode where, DartType from, DartType to) {
     // Note: we permit implicit downcasts.
     if (from != to &&
-        !environment.isSubtypeOf(from, to) &&
-        !environment.isSubtypeOf(to, from)) {
+        !environment.isSubtypeOf(
+            from, to, SubtypeCheckMode.ignoringNullabilities) &&
+        !environment.isSubtypeOf(
+            to, from, SubtypeCheckMode.ignoringNullabilities)) {
       failures.reportNotAssignable(where, from, to);
     }
   }
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 1e59288..363f5e7 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -20,7 +20,7 @@
 
 import '../type_algebra.dart' show Substitution, substitute;
 
-import '../type_environment.dart' show TypeEnvironment;
+import '../type_environment.dart' show SubtypeCheckMode, TypeEnvironment;
 
 import '../util/graph.dart' show Graph, computeStrongComponents;
 
@@ -275,7 +275,9 @@
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(argument, variables[i], type));
     } else if (!typeEnvironment.isSubtypeOf(
-        argument, substitute(variables[i].bound, substitutionMap))) {
+        argument,
+        substitute(variables[i].bound, substitutionMap),
+        SubtypeCheckMode.ignoringNullabilities)) {
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(argument, variables[i], type));
     }
@@ -321,7 +323,9 @@
       result
           .add(new TypeArgumentIssue(argumentsToReport[i], variables[i], type));
     } else if (!typeEnvironment.isSubtypeOf(
-        argument, substitute(variables[i].bound, substitutionMap))) {
+        argument,
+        substitute(variables[i].bound, substitutionMap),
+        SubtypeCheckMode.ignoringNullabilities)) {
       result ??= <TypeArgumentIssue>[];
       result
           .add(new TypeArgumentIssue(argumentsToReport[i], variables[i], type));
@@ -361,7 +365,9 @@
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(argument, parameters[i], null));
     } else if (!typeEnvironment.isSubtypeOf(
-        argument, substitute(parameters[i].bound, substitutionMap))) {
+        argument,
+        substitute(parameters[i].bound, substitutionMap),
+        SubtypeCheckMode.ignoringNullabilities)) {
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(argument, parameters[i], null));
     }
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 707b3a1..d3a9b1a 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1189,7 +1189,6 @@
     ++indentation;
     node.members.forEach((ExtensionMemberDescriptor descriptor) {
       writeIndentation();
-      writeModifier(descriptor.isExternal, 'external');
       writeModifier(descriptor.isStatic, 'static');
       switch (descriptor.kind) {
         case ExtensionMemberKind.Method:
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index cfd4617..cb25f2c 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -76,6 +76,12 @@
   return new _OccurrenceVisitor(variables).visit(type);
 }
 
+/// Returns `true` if [type] contains any free type variables, that is, type
+/// variable for function types whose function type is part of [type].
+bool containsFreeFunctionTypeVariables(DartType type) {
+  return new _FreeFunctionTypeVariableVisitor().visit(type);
+}
+
 /// Given a set of type variables, finds a substitution of those variables such
 /// that the two given types becomes equal, or returns `null` if no such
 /// substitution exists.
@@ -146,7 +152,8 @@
       typeParameters: freshTypeParameters,
       requiredParameterCount: type.requiredParameterCount,
       typedefType:
-          type.typedefType == null ? null : substitute(type.typedefType));
+          type.typedefType == null ? null : substitute(type.typedefType),
+      nullability: type.nullability);
 
   DartType substitute(DartType type) => substitution.substituteType(type);
 
@@ -440,7 +447,7 @@
     int before = useCounter;
     var typeArguments = node.typeArguments.map(visit).toList();
     if (useCounter == before) return node;
-    return new InterfaceType(node.classNode, typeArguments);
+    return new InterfaceType(node.classNode, typeArguments, node.nullability);
   }
 
   DartType visitTypedefType(TypedefType node) {
@@ -448,7 +455,7 @@
     int before = useCounter;
     var typeArguments = node.typeArguments.map(visit).toList();
     if (useCounter == before) return node;
-    return new TypedefType(node.typedefNode, typeArguments);
+    return new TypedefType(node.typedefNode, typeArguments, node.nullability);
   }
 
   List<TypeParameter> freshTypeParameters(List<TypeParameter> parameters) {
@@ -470,6 +477,13 @@
     // any uses, but does not tell if the resulting function type is distinct.
     // Our own use counter will get incremented if something from our
     // environment has been used inside the function.
+    assert(
+        node.typeParameters.every((TypeParameter parameter) =>
+            lookup(parameter, true) == null &&
+            lookup(parameter, false) == null),
+        "Function type variables cannot be substituted while still attached "
+        "to the function. Perform substitution on "
+        "`FunctionType.withoutTypeParameters` instead.");
     var inner = node.typeParameters.isEmpty ? this : newInnerEnvironment();
     int before = this.useCounter;
     // Invert the variance when translating parameters.
@@ -490,7 +504,8 @@
         namedParameters: namedParameters,
         typeParameters: typeParameters,
         requiredParameterCount: node.requiredParameterCount,
-        typedefType: typedefType);
+        typedefType: typedefType,
+        nullability: node.nullability);
   }
 
   void bumpCountersUntil(_TypeSubstitutor target) {
@@ -505,7 +520,7 @@
   DartType getSubstitute(TypeParameter variable) {
     var environment = this;
     while (environment != null) {
-      var replacement = environment.lookup(variable, covariantContext);
+      DartType replacement = environment.lookup(variable, covariantContext);
       if (replacement != null) {
         bumpCountersUntil(environment);
         return replacement;
@@ -515,8 +530,59 @@
     return null;
   }
 
+  /// Combines nullabilities of types during type substitution.
+  ///
+  /// In a type substitution, for example, when `int` is substituted for `T` in
+  /// `List<T?>`, the nullability of the occurrence of the type parameter should
+  /// be combined with the nullability of the type that is being substituted for
+  /// that type parameter.  In the example above it's the nullability of `T?`
+  /// and `int`.  The function computes the nullability for the replacement as
+  /// per the following table:
+  ///
+  /// | arg \ var |  !  |  ?  |  *  |  %  |
+  /// |-----------|-----|-----|-----|-----|
+  /// |     !     |  !  |  ?  |  *  |  !  |
+  /// |     ?     | N/A |  ?  |  ?  |  ?  |
+  /// |     *     |  *  |  ?  |  *  |  *  |
+  /// |     %     | N/A |  ?  |  *  |  %  |
+  ///
+  /// Here `!` denotes `Nullability.nonNullable`, `?` denotes
+  /// `Nullability.nullable`, `*` denotes `Nullability.legacy`, and `%` denotes
+  /// `Nullability.neither`.  The table elements marked with N/A denote the
+  /// cases that should yield a type error before the substitution is performed.
+  static Nullability combineNullabilitiesForSubstitution(
+      Nullability a, Nullability b) {
+    // In the table above we may extend the function given by it, replacing N/A
+    // with whatever is easier to implement.  In this implementation, we extend
+    // the table function as follows:
+    //
+    // | arg \ var |  !  |  ?  |  *  |  %  |
+    // |-----------|-----|-----|-----|-----|
+    // |     !     |  !  |  ?  |  *  |  !  |
+    // |     ?     |  ?  |  ?  |  ?  |  ?  |
+    // |     *     |  *  |  ?  |  *  |  *  |
+    // |     %     |  %  |  ?  |  *  |  %  |
+    //
+
+    if (a == Nullability.nullable || b == Nullability.nullable) {
+      return Nullability.nullable;
+    }
+
+    if (a == Nullability.legacy || b == Nullability.legacy) {
+      return Nullability.legacy;
+    }
+
+    return a;
+  }
+
   DartType visitTypeParameterType(TypeParameterType node) {
-    return getSubstitute(node.parameter) ?? node;
+    DartType replacement = getSubstitute(node.parameter);
+    if (replacement is InvalidType) return replacement;
+    if (replacement != null) {
+      return replacement.withNullability(combineNullabilitiesForSubstitution(
+          replacement.nullability, node.nullability));
+    }
+    return node;
   }
 }
 
@@ -713,7 +779,7 @@
   }
 }
 
-class _OccurrenceVisitor extends DartTypeVisitor<bool> {
+class _OccurrenceVisitor implements DartTypeVisitor<bool> {
   final Set<TypeParameter> variables;
 
   _OccurrenceVisitor(this.variables);
@@ -724,6 +790,11 @@
     return visit(node.type);
   }
 
+  bool defaultDartType(DartType node) {
+    throw new UnsupportedError("Unsupported type $node (${node.runtimeType}.");
+  }
+
+  bool visitBottomType(BottomType node) => false;
   bool visitInvalidType(InvalidType node) => false;
   bool visitDynamicType(DynamicType node) => false;
   bool visitVoidType(VoidType node) => false;
@@ -754,3 +825,53 @@
     return node.defaultType.accept(this);
   }
 }
+
+class _FreeFunctionTypeVariableVisitor implements DartTypeVisitor<bool> {
+  final Set<TypeParameter> variables = new Set<TypeParameter>();
+
+  _FreeFunctionTypeVariableVisitor();
+
+  bool visit(DartType node) => node.accept(this);
+
+  bool defaultDartType(DartType node) {
+    throw new UnsupportedError("Unsupported type $node (${node.runtimeType}.");
+  }
+
+  bool visitNamedType(NamedType node) {
+    return visit(node.type);
+  }
+
+  bool visitBottomType(BottomType node) => false;
+  bool visitInvalidType(InvalidType node) => false;
+  bool visitDynamicType(DynamicType node) => false;
+  bool visitVoidType(VoidType node) => false;
+
+  bool visitInterfaceType(InterfaceType node) {
+    return node.typeArguments.any(visit);
+  }
+
+  bool visitTypedefType(TypedefType node) {
+    return node.typeArguments.any(visit);
+  }
+
+  bool visitFunctionType(FunctionType node) {
+    variables.addAll(node.typeParameters);
+    bool result = node.typeParameters.any(handleTypeParameter) ||
+        node.positionalParameters.any(visit) ||
+        node.namedParameters.any(visitNamedType) ||
+        visit(node.returnType);
+    variables.removeAll(node.typeParameters);
+    return result;
+  }
+
+  bool visitTypeParameterType(TypeParameterType node) {
+    return node.parameter.parent == null && !variables.contains(node.parameter);
+  }
+
+  bool handleTypeParameter(TypeParameter node) {
+    assert(variables.contains(node));
+    if (node.bound.accept(this)) return true;
+    if (node.defaultType == null) return false;
+    return node.defaultType.accept(this);
+  }
+}
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index 31518fa..b6cfaa3 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -142,6 +142,51 @@
   }
 }
 
+/// The value enum for internal states of [IsSubtypeOf].
+enum _IsSubtypeOfValues {
+  always,
+  onlyIfIgnoringNullabilities,
+  never,
+}
+
+/// Result of a nullability-aware subtype check.
+///
+/// It is assumed that if a subtype check succeeds for two types in full-NNBD
+/// mode, it also succeeds for those two types if the nullability markers on the
+/// types and all of their sub-terms are ignored (that is, in the pre-NNBD
+/// mode).  By contraposition, if a subtype check fails for two types when the
+/// nullability markers are ignored, it should also fail for those types in
+/// full-NNBD mode.
+class IsSubtypeOf {
+  final _IsSubtypeOfValues _value;
+
+  /// Subtype check succeeds in both modes.
+  const IsSubtypeOf.always() : _value = _IsSubtypeOfValues.always;
+
+  /// Subtype check succeeds only if the nullability markers are ignored.
+  ///
+  /// This implies that if the nullability markers aren't ignored, the subtype
+  /// check fails.
+  const IsSubtypeOf.onlyIfIgnoringNullabilities()
+      : _value = _IsSubtypeOfValues.onlyIfIgnoringNullabilities;
+
+  /// Subtype check fails in both modes.
+  const IsSubtypeOf.never() : _value = _IsSubtypeOfValues.never;
+
+  bool isSubtypeWhenIgnoringNullabilities() {
+    return _value != _IsSubtypeOfValues.never;
+  }
+
+  bool isSubtypeWhenUsingNullabilities() {
+    return _value == _IsSubtypeOfValues.always;
+  }
+}
+
+enum SubtypeCheckMode {
+  withNullabilities,
+  ignoringNullabilities,
+}
+
 /// The part of [TypeEnvironment] that deals with subtype tests.
 ///
 /// This lives in a separate class so it can be tested independently of the SDK.
@@ -178,16 +223,36 @@
   }
 
   /// Returns true if [subtype] is a subtype of [supertype].
-  bool isSubtypeOf(DartType subtype, DartType supertype) {
+  bool isSubtypeOf(
+      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
+    IsSubtypeOf result =
+        performNullabilityAwareSubtypeCheck(subtype, supertype);
+    switch (mode) {
+      case SubtypeCheckMode.ignoringNullabilities:
+        return result.isSubtypeWhenIgnoringNullabilities();
+      case SubtypeCheckMode.withNullabilities:
+        return result.isSubtypeWhenUsingNullabilities();
+      default:
+        throw new StateError("Unhandled subtype checking mode '$mode'");
+    }
+  }
+
+  /// Performs a nullability-aware subtype check.
+  ///
+  /// The outcome is described in the comments to [IsSubtypeOf].
+  IsSubtypeOf performNullabilityAwareSubtypeCheck(
+      DartType subtype, DartType supertype) {
     subtype = subtype.unalias;
     supertype = supertype.unalias;
-    if (identical(subtype, supertype)) return true;
-    if (subtype is BottomType) return true;
+    if (identical(subtype, supertype)) return const IsSubtypeOf.always();
+    if (subtype is BottomType) return const IsSubtypeOf.always();
     if (subtype == nullType) {
       // See rule 4 of the subtype rules from the Dart Language Specification.
-      return supertype is! BottomType;
+      return supertype is BottomType
+          ? const IsSubtypeOf.never()
+          : const IsSubtypeOf.always();
     }
-    if (isTop(supertype)) return true;
+    if (isTop(supertype)) return const IsSubtypeOf.always();
 
     // Handle FutureOr<T> union type.
     if (subtype is InterfaceType &&
@@ -197,14 +262,18 @@
           identical(supertype.classNode, futureOrClass)) {
         var supertypeArg = supertype.typeArguments[0];
         // FutureOr<A> <: FutureOr<B> iff A <: B
-        return isSubtypeOf(subtypeArg, supertypeArg);
+        return performNullabilityAwareSubtypeCheck(subtypeArg, supertypeArg);
       }
 
       // given t1 is Future<A> | A, then:
       // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
       var subtypeFuture = futureType(subtypeArg);
-      return isSubtypeOf(subtypeFuture, supertype) &&
-          isSubtypeOf(subtypeArg, supertype);
+      return performNullabilityAwareSubtypeCheck(subtypeFuture, supertype)
+                  .isSubtypeWhenIgnoringNullabilities() &&
+              performNullabilityAwareSubtypeCheck(subtypeArg, supertype)
+                  .isSubtypeWhenIgnoringNullabilities()
+          ? const IsSubtypeOf.always()
+          : const IsSubtypeOf.never();
     }
 
     if (supertype is InterfaceType &&
@@ -213,58 +282,67 @@
       // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
       var supertypeArg = supertype.typeArguments[0];
       var supertypeFuture = futureType(supertypeArg);
-      return isSubtypeOf(subtype, supertypeFuture) ||
-          isSubtypeOf(subtype, supertypeArg);
+      return performNullabilityAwareSubtypeCheck(subtype, supertypeFuture)
+                  .isSubtypeWhenIgnoringNullabilities() ||
+              performNullabilityAwareSubtypeCheck(subtype, supertypeArg)
+                  .isSubtypeWhenIgnoringNullabilities()
+          ? const IsSubtypeOf.always()
+          : const IsSubtypeOf.never();
     }
 
     if (subtype is InterfaceType && supertype is InterfaceType) {
       var upcastType = getTypeAsInstanceOf(subtype, supertype.classNode);
-      if (upcastType == null) return false;
+      if (upcastType == null) return const IsSubtypeOf.never();
       for (int i = 0; i < upcastType.typeArguments.length; ++i) {
         // Termination: the 'supertype' parameter decreases in size.
-        if (!isSubtypeOf(
-            upcastType.typeArguments[i], supertype.typeArguments[i])) {
-          return false;
+        if (!performNullabilityAwareSubtypeCheck(
+                upcastType.typeArguments[i], supertype.typeArguments[i])
+            .isSubtypeWhenIgnoringNullabilities()) {
+          return const IsSubtypeOf.never();
         }
       }
-      return true;
+      return const IsSubtypeOf.always();
     }
     if (subtype is TypeParameterType) {
       if (supertype is TypeParameterType &&
           subtype.parameter == supertype.parameter) {
         if (supertype.promotedBound != null) {
-          return isSubtypeOf(subtype.bound, supertype.bound);
+          return performNullabilityAwareSubtypeCheck(
+              subtype.bound, supertype.bound);
         } else {
           // Promoted bound should always be a subtype of the declared bound.
           assert(subtype.promotedBound == null ||
-              isSubtypeOf(subtype.bound, supertype.bound));
-          return true;
+              performNullabilityAwareSubtypeCheck(
+                      subtype.bound, supertype.bound)
+                  .isSubtypeWhenIgnoringNullabilities());
+          return const IsSubtypeOf.always();
         }
       }
       // Termination: if there are no cyclically bound type parameters, this
       // recursive call can only occur a finite number of times, before reaching
       // a shrinking recursive call (or terminating).
-      return isSubtypeOf(subtype.bound, supertype);
+      return performNullabilityAwareSubtypeCheck(subtype.bound, supertype);
     }
     if (subtype is FunctionType) {
-      if (supertype == functionLegacyRawType) return true;
+      if (supertype == functionLegacyRawType) return const IsSubtypeOf.always();
       if (supertype is FunctionType) {
-        return _isFunctionSubtypeOf(subtype, supertype);
+        return _performNullabilityAwareFunctionSubtypeCheck(subtype, supertype);
       }
     }
-    return false;
+    return const IsSubtypeOf.never();
   }
 
-  bool _isFunctionSubtypeOf(FunctionType subtype, FunctionType supertype) {
+  IsSubtypeOf _performNullabilityAwareFunctionSubtypeCheck(
+      FunctionType subtype, FunctionType supertype) {
     if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
-      return false;
+      return const IsSubtypeOf.never();
     }
     if (subtype.positionalParameters.length <
         supertype.positionalParameters.length) {
-      return false;
+      return const IsSubtypeOf.never();
     }
     if (subtype.typeParameters.length != supertype.typeParameters.length) {
-      return false;
+      return const IsSubtypeOf.never();
     }
     if (subtype.typeParameters.isNotEmpty) {
       var substitution = <TypeParameter, DartType>{};
@@ -281,22 +359,28 @@
         // recursive call can only occur a finite number of times before
         // reaching a shrinking recursive call (or terminating).
         // TODO(dmitryas): Replace it with one recursive descent instead of two.
-        if (!isSubtypeOf(superParameter.bound, subBound) ||
-            !isSubtypeOf(subBound, superParameter.bound)) {
-          return false;
+        if (!performNullabilityAwareSubtypeCheck(superParameter.bound, subBound)
+                .isSubtypeWhenIgnoringNullabilities() ||
+            !performNullabilityAwareSubtypeCheck(subBound, superParameter.bound)
+                .isSubtypeWhenIgnoringNullabilities()) {
+          return const IsSubtypeOf.never();
         }
       }
       subtype = substitute(subtype.withoutTypeParameters, substitution);
     }
-    if (!isSubtypeOf(subtype.returnType, supertype.returnType)) {
-      return false;
+    if (!performNullabilityAwareSubtypeCheck(
+            subtype.returnType, supertype.returnType)
+        .isSubtypeWhenIgnoringNullabilities()) {
+      return const IsSubtypeOf.never();
     }
     for (int i = 0; i < supertype.positionalParameters.length; ++i) {
       var supertypeParameter = supertype.positionalParameters[i];
       var subtypeParameter = subtype.positionalParameters[i];
       // Termination: Both types shrink in size.
-      if (!isSubtypeOf(supertypeParameter, subtypeParameter)) {
-        return false;
+      if (!performNullabilityAwareSubtypeCheck(
+              supertypeParameter, subtypeParameter)
+          .isSubtypeWhenIgnoringNullabilities()) {
+        return const IsSubtypeOf.never();
       }
     }
     int subtypeNameIndex = 0;
@@ -306,13 +390,17 @@
               supertypeParameter.name) {
         ++subtypeNameIndex;
       }
-      if (subtypeNameIndex == subtype.namedParameters.length) return false;
+      if (subtypeNameIndex == subtype.namedParameters.length) {
+        return const IsSubtypeOf.never();
+      }
       NamedType subtypeParameter = subtype.namedParameters[subtypeNameIndex];
       // Termination: Both types shrink in size.
-      if (!isSubtypeOf(supertypeParameter.type, subtypeParameter.type)) {
-        return false;
+      if (!performNullabilityAwareSubtypeCheck(
+              supertypeParameter.type, subtypeParameter.type)
+          .isSubtypeWhenIgnoringNullabilities()) {
+        return const IsSubtypeOf.never();
       }
     }
-    return true;
+    return const IsSubtypeOf.always();
   }
 }
diff --git a/pkg/kernel/test/load_concat_dill_keeps_source_test.dart b/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
new file mode 100644
index 0000000..3226148
--- /dev/null
+++ b/pkg/kernel/test/load_concat_dill_keeps_source_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that 79cc54e51924cd5a6bdc2bd1771f2d0ee7af8899 works as intended.
+
+import 'dart:convert';
+
+import 'package:kernel/binary/ast_from_binary.dart';
+import 'package:kernel/binary/ast_to_binary.dart';
+import 'package:kernel/kernel.dart';
+
+Uri uri1 = Uri.parse("foo://lib1.dart");
+Uri uri2 = Uri.parse("foo://lib2.dart");
+
+main() {
+  Library library1 = new Library(uri1)..fileUri = uri1;
+  Library library2 = new Library(uri2)..fileUri = uri2;
+  Procedure p1 = new Procedure(new Name("p1"), ProcedureKind.Method,
+      new FunctionNode(new ReturnStatement()))
+    ..fileUri = uri2;
+  Procedure p2 = new Procedure(new Name("p2"), ProcedureKind.Method,
+      new FunctionNode(new ReturnStatement()))
+    ..fileUri = uri1;
+  library1.addMember(p1);
+  library2.addMember(p2);
+
+  Component component = new Component(libraries: [library1, library2]);
+  component.uriToSource[uri1] = new Source(
+      [42, 2 * 42], const Utf8Encoder().convert("source #1"), uri1, uri1);
+  component.uriToSource[uri2] = new Source(
+      [43, 3 * 43], const Utf8Encoder().convert("source #2"), uri1, uri1);
+  expectSource(serialize(component), true, true);
+
+  Component cPartial1 = new Component(nameRoot: component.root)
+    ..libraries.add(library1);
+  cPartial1.uriToSource[uri1] = new Source(
+      [42, 2 * 42], const Utf8Encoder().convert("source #1"), uri1, uri1);
+  cPartial1.uriToSource[uri2] =
+      new Source([43, 3 * 43], const <int>[], uri1, uri1);
+  List<int> partial1Serialized = serialize(cPartial1);
+  expectSource(partial1Serialized, true, false);
+
+  Component cPartial2 = new Component(nameRoot: component.root)
+    ..libraries.add(library2);
+  cPartial2.uriToSource[uri1] =
+      new Source([42, 2 * 42], const <int>[], uri1, uri1);
+  cPartial2.uriToSource[uri2] = new Source(
+      [43, 3 * 43], const Utf8Encoder().convert("source #2"), uri1, uri1);
+  List<int> partial2Serialized = serialize(cPartial2);
+  expectSource(partial2Serialized, false, true);
+
+  List<int> combined = new List<int>();
+  combined.addAll(partial1Serialized);
+  combined.addAll(partial2Serialized);
+  expectSource(combined, true, true);
+}
+
+void expectSource(List<int> data, bool expect1, bool expect2) {
+  BinaryBuilder builder = new BinaryBuilder(data);
+  Component tmp = new Component();
+  builder.readComponent(tmp);
+  if (tmp.uriToSource[uri1] == null) throw "No data for $uri1";
+  if (tmp.uriToSource[uri2] == null) throw "No data for $uri2";
+  if (expect1 && tmp.uriToSource[uri1].source.isEmpty) {
+    throw "No data for $uri1";
+  }
+  if (!expect1 && tmp.uriToSource[uri1].source.isNotEmpty) {
+    throw "Unexpected data for $uri1";
+  }
+  if (expect2 && tmp.uriToSource[uri2].source.isEmpty) {
+    throw "No data data for $uri2";
+  }
+  if (!expect2 && tmp.uriToSource[uri2].source.isNotEmpty) {
+    throw "Unexpected data for $uri2";
+  }
+}
+
+List<int> serialize(Component c) {
+  SimpleSink sink = new SimpleSink();
+  BinaryPrinter printerWhole = new BinaryPrinter(sink);
+  printerWhole.writeComponentFile(c);
+  List<int> result = new List<int>();
+  for (List<int> chunk in sink.chunks) {
+    result.addAll(chunk);
+  }
+  return result;
+}
+
+class SimpleSink implements Sink<List<int>> {
+  final List<List<int>> chunks = <List<int>>[];
+
+  @override
+  void add(List<int> chunk) {
+    chunks.add(chunk);
+  }
+
+  @override
+  void close() {}
+}
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 7689928..7b52b3c 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -70,6 +70,11 @@
   /// - Its [destinationNode] is nullable.
   bool get isSatisfied;
 
+  /// Indicates whether all the upstream nodes of this edge are nullable (and
+  /// thus downstream nullability propagation should try to make the destination
+  /// node nullable, if possible).
+  bool get isTriggered;
+
   /// A boolean indicating whether the graph edge is a "union" edge.  Union
   /// edges are edges for which the nullability propagation algorithm tries to
   /// ensure that both the [sourceNode] and the [destinationNode] have the
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
new file mode 100644
index 0000000..272fe5d
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -0,0 +1,254 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:front_end/src/fasta/flow_analysis/flow_analysis.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
+import 'package:nnbd_migration/src/variables.dart';
+
+/// This class visits the AST of code being migrated, after graph propagation,
+/// to figure out what changes need to be made to the code.  It doesn't actually
+/// make the changes; it simply reports what changes are necessary through
+/// abstract methods.
+abstract class FixBuilder extends GeneralizingAstVisitor<DartType> {
+  /// The decorated class hierarchy for this migration run.
+  final DecoratedClassHierarchy _decoratedClassHierarchy;
+
+  /// Type provider providing non-nullable types.
+  final TypeProvider _typeProvider;
+
+  /// The type system.
+  final TypeSystem _typeSystem;
+
+  /// Variables for this migration run.
+  final Variables _variables;
+
+  /// If we are visiting a function body or initializer, instance of flow
+  /// analysis.  Otherwise `null`.
+  FlowAnalysis<Statement, Expression, PromotableElement, DartType>
+      _flowAnalysis;
+
+  /// If we are visiting a function body or initializer, assigned variable
+  /// information  used in flow analysis.  Otherwise `null`.
+  AssignedVariables<AstNode, VariableElement> _assignedVariables;
+
+  /// If we are visiting a subexpression, the context type used for type
+  /// inference.  This is used to determine when `!` needs to be inserted.
+  DartType _contextType;
+
+  FixBuilder(this._decoratedClassHierarchy, TypeProvider typeProvider,
+      this._typeSystem, this._variables)
+      : _typeProvider = (typeProvider as TypeProviderImpl)
+            .withNullability(NullabilitySuffix.none);
+
+  /// Called whenever an expression is found for which a `!` needs to be
+  /// inserted.
+  void addNullCheck(Expression subexpression);
+
+  /// Initializes flow analysis for a function node.
+  void createFlowAnalysis(AstNode node) {
+    assert(_flowAnalysis == null);
+    assert(_assignedVariables == null);
+    _flowAnalysis =
+        FlowAnalysis<Statement, Expression, PromotableElement, DartType>(
+            const AnalyzerNodeOperations(),
+            TypeSystemTypeOperations(_typeSystem),
+            AnalyzerFunctionBodyAccess(node is FunctionBody ? node : null));
+    _assignedVariables = FlowAnalysisHelper.computeAssignedVariables(node);
+  }
+
+  @override
+  DartType visitBinaryExpression(BinaryExpression node) {
+    var leftOperand = node.leftOperand;
+    var rightOperand = node.rightOperand;
+    var operatorType = node.operator.type;
+    var staticElement = node.staticElement;
+    switch (operatorType) {
+      case TokenType.BANG_EQ:
+      case TokenType.EQ_EQ:
+        visitSubexpression(leftOperand, _typeProvider.dynamicType);
+        visitSubexpression(rightOperand, _typeProvider.dynamicType);
+        if (leftOperand is SimpleIdentifier && rightOperand is NullLiteral) {
+          var leftElement = leftOperand.staticElement;
+          if (leftElement is PromotableElement) {
+            _flowAnalysis.conditionEqNull(node, leftElement,
+                notEqual: operatorType == TokenType.BANG_EQ);
+          }
+        }
+        return _typeProvider.boolType;
+      case TokenType.AMPERSAND_AMPERSAND:
+      case TokenType.BAR_BAR:
+        var isAnd = operatorType == TokenType.AMPERSAND_AMPERSAND;
+        visitSubexpression(leftOperand, _typeProvider.boolType);
+        _flowAnalysis.logicalBinaryOp_rightBegin(leftOperand, isAnd: isAnd);
+        visitSubexpression(rightOperand, _typeProvider.boolType);
+        _flowAnalysis.logicalBinaryOp_end(node, rightOperand, isAnd: isAnd);
+        return _typeProvider.boolType;
+      case TokenType.QUESTION_QUESTION:
+        // If `a ?? b` is used in a non-nullable context, we don't want to
+        // migrate it to `(a ?? b)!`.  We want to migrate it to `a ?? b!`.
+        // TODO(paulberry): once flow analysis supports `??`, integrate it here.
+        var leftType = visitSubexpression(node.leftOperand,
+            _typeSystem.makeNullable(_contextType as TypeImpl));
+        var rightType = visitSubexpression(node.rightOperand, _contextType);
+        return _typeSystem.leastUpperBound(
+            _typeSystem.promoteToNonNull(leftType as TypeImpl), rightType);
+      default:
+        var targetType =
+            visitSubexpression(leftOperand, _typeProvider.objectType);
+        DartType contextType;
+        DartType returnType;
+        if (staticElement == null) {
+          contextType = _typeProvider.dynamicType;
+          returnType = _typeProvider.dynamicType;
+        } else {
+          var methodType =
+              _computeMigratedType(staticElement, targetType: targetType)
+                  as FunctionType;
+          contextType = methodType.parameters[0].type;
+          returnType = methodType.returnType;
+        }
+        visitSubexpression(rightOperand, contextType);
+        return _fixNumericTypes(returnType, node.staticType);
+    }
+  }
+
+  @override
+  DartType visitExpression(Expression node) {
+    // Every expression type needs its own visit method.
+    throw UnimplementedError('No visit method for ${node.runtimeType}');
+  }
+
+  @override
+  DartType visitLiteral(Literal node) {
+    if (node is AdjacentStrings) {
+      // TODO(paulberry): need to visit interpolations
+      throw UnimplementedError('TODO(paulberry)');
+    }
+    if (node is TypedLiteral) {
+      throw UnimplementedError('TODO(paulberry)');
+    }
+    return (node.staticType as TypeImpl)
+        .withNullability(NullabilitySuffix.none);
+  }
+
+  @override
+  DartType visitParenthesizedExpression(ParenthesizedExpression node) {
+    return node.expression.accept(this);
+  }
+
+  @override
+  DartType visitSimpleIdentifier(SimpleIdentifier node) {
+    var element = node.staticElement;
+    if (element == null) return _typeProvider.dynamicType;
+    if (element is PromotableElement) {
+      var promotedType = _flowAnalysis.promotedType(element);
+      if (promotedType != null) return promotedType;
+    }
+    return _computeMigratedType(element);
+  }
+
+  /// Recursively visits a subexpression, providing a context type.
+  DartType visitSubexpression(Expression subexpression, DartType contextType) {
+    var oldContextType = _contextType;
+    try {
+      _contextType = contextType;
+      var type = subexpression.accept(this);
+      if (_doesAssignmentNeedCheck(from: type, to: contextType)) {
+        addNullCheck(subexpression);
+        return _typeSystem.promoteToNonNull(type as TypeImpl);
+      } else {
+        return type;
+      }
+    } finally {
+      _contextType = oldContextType;
+    }
+  }
+
+  /// Computes the type that [element] will have after migration.
+  ///
+  /// If [targetType] is present, and [element] is a class member, it is the
+  /// type of the class within which [element] is being accessed; this is used
+  /// to perform the correct substitutions.
+  DartType _computeMigratedType(Element element, {DartType targetType}) {
+    Element baseElement;
+    if (element is Member) {
+      assert(targetType != null);
+      baseElement = element.baseElement;
+    } else {
+      baseElement = element;
+    }
+    DartType type;
+    if (baseElement is ClassElement || baseElement is TypeParameterElement) {
+      return _typeProvider.typeType;
+    } else if (baseElement is PropertyAccessorElement) {
+      if (baseElement.isSynthetic) {
+        type = _variables
+            .decoratedElementType(baseElement.variable)
+            .toFinalType(_typeProvider);
+      } else {
+        var functionType = _variables.decoratedElementType(baseElement);
+        var decoratedType = baseElement.isGetter
+            ? functionType.returnType
+            : throw UnimplementedError('TODO(paulberry)');
+        type = decoratedType.toFinalType(_typeProvider);
+      }
+    } else {
+      type = _variables
+          .decoratedElementType(baseElement)
+          .toFinalType(_typeProvider);
+    }
+    if (targetType is InterfaceType && targetType.typeArguments.isNotEmpty) {
+      var superclass = baseElement.enclosingElement as ClassElement;
+      var class_ = targetType.element;
+      if (class_ != superclass) {
+        var supertype = _decoratedClassHierarchy
+            .getDecoratedSupertype(class_, superclass)
+            .toFinalType(_typeProvider) as InterfaceType;
+        type = Substitution.fromInterfaceType(supertype).substituteType(type);
+      }
+      return substitute(type, {
+        for (int i = 0; i < targetType.typeArguments.length; i++)
+          class_.typeParameters[i]: targetType.typeArguments[i]
+      });
+    } else {
+      return type;
+    }
+  }
+
+  /// Determines whether a null check is needed when assigning a value of type
+  /// [from] to a context of type [to].
+  bool _doesAssignmentNeedCheck(
+      {@required DartType from, @required DartType to}) {
+    return !from.isDynamic &&
+        _typeSystem.isNullable(from) &&
+        !_typeSystem.isNullable(to);
+  }
+
+  /// Determines whether a `num` type originating from a call to a
+  /// user-definable operator needs to be changed to `int`.  [type] is the type
+  /// determined by naive operator lookup; [originalType] is the type that was
+  /// determined by the analyzer's full resolution algorithm when analyzing the
+  /// pre-migrated code.
+  DartType _fixNumericTypes(DartType type, DartType originalType) {
+    if (type.isDartCoreNum && originalType.isDartCoreInt) {
+      return (originalType as TypeImpl)
+          .withNullability((type as TypeImpl).nullabilitySuffix);
+    } else {
+      return type;
+    }
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 3c057df..0711d42 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -34,26 +34,24 @@
 
   @override
   bool get isSatisfied {
-    if (!_isTriggered) return true;
+    if (!isTriggered) return true;
     return destinationNode.isNullable;
   }
 
   @override
+  bool get isTriggered {
+    for (var upstreamNode in upstreamNodes) {
+      if (!upstreamNode.isNullable) return false;
+    }
+    return true;
+  }
+
+  @override
   bool get isUnion => _kind == _NullabilityEdgeKind.union;
 
   @override
   NullabilityNode get sourceNode => upstreamNodes.first;
 
-  /// Indicates whether all the upstream nodes of this edge are nullable (and
-  /// thus downstream nullability propagation should try to make the destination
-  /// node nullable, if possible).
-  bool get _isTriggered {
-    for (var upstreamNode in upstreamNodes) {
-      if (!upstreamNode.isNullable) return false;
-    }
-    return true;
-  }
-
   @override
   String toString() {
     var edgeDecorations = <Object>[];
@@ -249,7 +247,7 @@
     while (true) {
       while (_pendingEdges.isNotEmpty) {
         var edge = _pendingEdges.removeLast();
-        if (!edge._isTriggered) continue;
+        if (!edge.isTriggered) continue;
         var node = edge.destinationNode;
         if (node._state == NullabilityState.nonNullable) {
           // The node has already been marked as non-nullable, so the edge can't
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
new file mode 100644
index 0000000..820f271
--- /dev/null
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -0,0 +1,369 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
+import 'package:nnbd_migration/src/fix_builder.dart';
+import 'package:nnbd_migration/src/variables.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FixBuilderTest);
+  });
+}
+
+@reflectiveTest
+class FixBuilderTest extends EdgeBuilderTestBase {
+  DartType get dynamicType => postMigrationTypeProvider.dynamicType;
+
+  DartType get objectType => postMigrationTypeProvider.objectType;
+
+  TypeProvider get postMigrationTypeProvider =>
+      (typeProvider as TypeProviderImpl)
+          .withNullability(NullabilitySuffix.none);
+
+  @override
+  Future<CompilationUnit> analyze(String code) async {
+    var unit = await super.analyze(code);
+    graph.propagate();
+    return unit;
+  }
+
+  test_binaryExpression_ampersand_ampersand() async {
+    await analyze('''
+_f(bool x, bool y) => x && y;
+''');
+    visitSubexpression(findNode.binary('&&'), 'bool');
+  }
+
+  test_binaryExpression_ampersand_ampersand_flow() async {
+    await analyze('''
+_f(bool/*?*/ x) => x != null && x;
+''');
+    visitSubexpression(findNode.binary('&&'), 'bool');
+  }
+
+  test_binaryExpression_ampersand_ampersand_nullChecked() async {
+    await analyze('''
+_f(bool/*?*/ x, bool/*?*/ y) => x && y;
+''');
+    var xRef = findNode.simple('x &&');
+    var yRef = findNode.simple('y;');
+    visitSubexpression(findNode.binary('&&'), 'bool',
+        nullChecked: {xRef, yRef});
+  }
+
+  test_binaryExpression_bang_eq() async {
+    await analyze('''
+_f(Object/*?*/ x, Object/*?*/ y) => x != y;
+''');
+    visitSubexpression(findNode.binary('!='), 'bool');
+  }
+
+  test_binaryExpression_bar_bar() async {
+    await analyze('''
+_f(bool x, bool y) {
+  return x || y;
+}
+''');
+    visitSubexpression(findNode.binary('||'), 'bool');
+  }
+
+  test_binaryExpression_bar_bar_flow() async {
+    await analyze('''
+_f(bool/*?*/ x) {
+  return x == null || x;
+}
+''');
+    visitSubexpression(findNode.binary('||'), 'bool');
+  }
+
+  test_binaryExpression_bar_bar_nullChecked() async {
+    await analyze('''
+_f(Object/*?*/ x, Object/*?*/ y) {
+  return x || y;
+}
+''');
+    var xRef = findNode.simple('x ||');
+    var yRef = findNode.simple('y;');
+    visitSubexpression(findNode.binary('||'), 'bool',
+        nullChecked: {xRef, yRef});
+  }
+
+  test_binaryExpression_eq_eq() async {
+    await analyze('''
+_f(Object/*?*/ x, Object/*?*/ y) {
+  return x == y;
+}
+''');
+    visitSubexpression(findNode.binary('=='), 'bool');
+  }
+
+  test_binaryExpression_question_question() async {
+    await analyze('''
+_f(int/*?*/ x, double/*?*/ y) {
+  return x ?? y;
+}
+''');
+    visitSubexpression(findNode.binary('??'), 'num?');
+  }
+
+  test_binaryExpression_question_question_nullChecked() async {
+    await analyze('''
+Object/*!*/ _f(int/*?*/ x, double/*?*/ y) {
+  return x ?? y;
+}
+''');
+    var yRef = findNode.simple('y;');
+    visitSubexpression(findNode.binary('??'), 'num',
+        contextType: objectType, nullChecked: {yRef});
+  }
+
+  test_binaryExpression_userDefinable_dynamic() async {
+    await analyze('''
+Object/*!*/ _f(dynamic d, int/*?*/ i) => d + i;
+''');
+    visitSubexpression(findNode.binary('+'), 'dynamic',
+        contextType: objectType);
+  }
+
+  test_binaryExpression_userDefinable_intRules() async {
+    await analyze('''
+_f(int i, int j) => i + j;
+''');
+    visitSubexpression(findNode.binary('+'), 'int');
+  }
+
+  test_binaryExpression_userDefinable_simple() async {
+    await analyze('''
+class _C {
+  int operator+(String s) => 1;
+}
+_f(_C c) => c + 'foo';
+''');
+    visitSubexpression(findNode.binary('c +'), 'int');
+  }
+
+  test_binaryExpression_userDefinable_simple_check_lhs() async {
+    await analyze('''
+class _C {
+  int operator+(String s) => 1;
+}
+_f(_C/*?*/ c) => c + 'foo';
+''');
+    visitSubexpression(findNode.binary('c +'), 'int',
+        nullChecked: {findNode.simple('c +')});
+  }
+
+  test_binaryExpression_userDefinable_simple_check_rhs() async {
+    await analyze('''
+class _C {
+  int operator+(String/*!*/ s) => 1;
+}
+_f(_C c, String/*?*/ s) => c + s;
+''');
+    visitSubexpression(findNode.binary('c +'), 'int',
+        nullChecked: {findNode.simple('s;')});
+  }
+
+  test_binaryExpression_userDefinable_substituted() async {
+    await analyze('''
+class _C<T, U> {
+  T operator+(U u) => throw 'foo';
+}
+_f(_C<int, String> c) => c + 'foo';
+''');
+    visitSubexpression(findNode.binary('c +'), 'int');
+  }
+
+  test_binaryExpression_userDefinable_substituted_check_rhs() async {
+    await analyze('''
+class _C<T, U> {
+  T operator+(U u) => throw 'foo';
+}
+_f(_C<int, String/*!*/> c, String/*?*/ s) => c + s;
+''');
+    visitSubexpression(findNode.binary('c +'), 'int',
+        nullChecked: {findNode.simple('s;')});
+  }
+
+  test_binaryExpression_userDefinable_substituted_no_check_rhs() async {
+    await analyze('''
+class _C<T, U> {
+  T operator+(U u) => throw 'foo';
+}
+_f(_C<int, String/*?*/> c, String/*?*/ s) => c + s;
+''');
+    visitSubexpression(findNode.binary('c +'), 'int');
+  }
+
+  test_booleanLiteral() async {
+    await analyze('''
+f() => true;
+''');
+    visitSubexpression(findNode.booleanLiteral('true'), 'bool');
+  }
+
+  test_doubleLiteral() async {
+    await analyze('''
+f() => 1.0;
+''');
+    visitSubexpression(findNode.doubleLiteral('1.0'), 'double');
+  }
+
+  test_integerLiteral() async {
+    await analyze('''
+f() => 1;
+''');
+    visitSubexpression(findNode.integerLiteral('1'), 'int');
+  }
+
+  test_nullLiteral() async {
+    await analyze('''
+f() => null;
+''');
+    visitSubexpression(findNode.nullLiteral('null'), 'Null');
+  }
+
+  test_parenthesizedExpression() async {
+    await analyze('''
+f() => (1);
+''');
+    visitSubexpression(findNode.integerLiteral('1'), 'int');
+  }
+
+  test_simpleIdentifier_className() async {
+    await analyze('''
+_f() => int;
+''');
+    visitSubexpression(findNode.simple('int'), 'Type');
+  }
+
+  test_simpleIdentifier_field() async {
+    await analyze('''
+class _C {
+  int i = 1;
+  f() => i;
+}
+''');
+    visitSubexpression(findNode.simple('i;'), 'int');
+  }
+
+  test_simpleIdentifier_field_generic() async {
+    await analyze('''
+class _C<T> {
+  List<T> x = null;
+  f() => x;
+}
+''');
+    visitSubexpression(findNode.simple('x;'), 'List<T>?');
+  }
+
+  test_simpleIdentifier_field_nullable() async {
+    await analyze('''
+class _C {
+  int/*?*/ i = 1;
+  f() => i;
+}
+''');
+    visitSubexpression(findNode.simple('i;'), 'int?');
+  }
+
+  test_simpleIdentifier_getter() async {
+    await analyze('''
+class _C {
+  int get i => 1;
+  f() => i;
+}
+''');
+    visitSubexpression(findNode.simple('i;'), 'int');
+  }
+
+  test_simpleIdentifier_getter_nullable() async {
+    await analyze('''
+class _C {
+  int/*?*/ get i => 1;
+  f() => i;
+}
+''');
+    visitSubexpression(findNode.simple('i;'), 'int?');
+  }
+
+  test_simpleIdentifier_localVariable_nonNullable() async {
+    await analyze('''
+_f(int x) {
+  return x;
+}
+''');
+    visitSubexpression(findNode.simple('x;'), 'int');
+  }
+
+  test_simpleIdentifier_localVariable_nullable() async {
+    await analyze('''
+_f(int/*?*/ x) {
+  return x;
+}
+''');
+    visitSubexpression(findNode.simple('x;'), 'int?');
+  }
+
+  test_stringLiteral() async {
+    await analyze('''
+f() => 'foo';
+''');
+    visitSubexpression(findNode.stringLiteral("'foo'"), 'String');
+  }
+
+  test_symbolLiteral() async {
+    await analyze('''
+f() => #foo;
+''');
+    visitSubexpression(findNode.symbolLiteral('#foo'), 'Symbol');
+  }
+
+  test_use_of_dynamic() async {
+    // Use of `dynamic` in a context requiring non-null is not explicitly null
+    // checked.
+    await analyze('''
+bool _f(dynamic d, bool b) => d && b;
+''');
+    visitSubexpression(findNode.binary('&&'), 'bool');
+  }
+
+  void visitSubexpression(Expression node, String expectedType,
+      {DartType contextType,
+      Set<Expression> nullChecked = const <Expression>{}}) {
+    contextType ??= dynamicType;
+    var fixBuilder = _FixBuilder(
+        decoratedClassHierarchy, typeProvider, typeSystem, variables);
+    fixBuilder.createFlowAnalysis(node.thisOrAncestorOfType<FunctionBody>());
+    var type = fixBuilder.visitSubexpression(node, contextType);
+    expect((type as TypeImpl).toString(withNullability: true), expectedType);
+    expect(fixBuilder.nullCheckedExpressions, nullChecked);
+  }
+}
+
+class _FixBuilder extends FixBuilder {
+  final Set<Expression> nullCheckedExpressions = {};
+
+  _FixBuilder(DecoratedClassHierarchy decoratedClassHierarchy,
+      TypeProvider typeProvider, TypeSystem typeSystem, Variables variables)
+      : super(decoratedClassHierarchy, typeProvider, typeSystem, variables);
+
+  @override
+  void addNullCheck(Expression subexpression) {
+    var newlyAdded = nullCheckedExpressions.add(subexpression);
+    expect(newlyAdded, true);
+  }
+}
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index fed8c12..672ee30 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -12,6 +12,7 @@
 import 'edge_builder_flow_analysis_test.dart'
     as edge_builder_flow_analysis_test;
 import 'edge_builder_test.dart' as edge_builder_test;
+import 'fix_builder_test.dart' as fix_builder_test;
 import 'instrumentation_test.dart' as instrumentation_test;
 import 'node_builder_test.dart' as node_builder_test;
 import 'nullability_migration_impl_test.dart'
@@ -27,6 +28,7 @@
     decorated_type_test.main();
     edge_builder_flow_analysis_test.main();
     edge_builder_test.main();
+    fix_builder_test.main();
     instrumentation_test.main();
     node_builder_test.main();
     nullability_migration_impl_test.main();
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index eefe915..ed2ab26 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:io' show exit;
+import 'dart:io' as io;
 
 import 'package:args/args.dart' show ArgParser;
 import 'package:kernel/text/ast_to_text.dart'
@@ -31,7 +31,7 @@
   if (arguments.isNotEmpty && arguments.last == '--batch') {
     await runBatchModeCompiler();
   } else {
-    exit(await compile(arguments));
+    io.exitCode = await compile(arguments);
   }
 }
 
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index 5926c77..f4969eb 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -394,6 +394,11 @@
     _emitInstructionDF(Opcode.kDirectCall, rd, rf);
   }
 
+  void emitUncheckedDirectCall(int rd, int rf) {
+    emitSourcePositionForCall();
+    _emitInstructionDF(Opcode.kUncheckedDirectCall, rd, rf);
+  }
+
   void emitInterfaceCall(int rd, int rf) {
     emitSourcePositionForCall();
     _emitInstructionDF(Opcode.kInterfaceCall, rd, rf);
@@ -565,4 +570,9 @@
     emitSourcePosition();
     _emitInstructionD(Opcode.kAllocateClosure, rd);
   }
+
+  void emitCheckReceiverForNull(int rd) {
+    emitSourcePosition();
+    _emitInstructionD(Opcode.kCheckReceiverForNull, rd);
+  }
 }
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index eeee7fc..481e0c2 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -113,6 +113,13 @@
   PackedObject argDesc;
 }
 
+// Occupies 2 entries in the constant pool.
+type ConstantDirectCallViaDynamicForwarder extends ConstantPoolEntry {
+  Byte tag = 32;
+  PackedObject target;
+  PackedObject argDesc;
+}
+
 */
 
 enum ConstantTag {
@@ -148,6 +155,7 @@
   kInterfaceCall,
   kInstantiatedInterfaceCall,
   kDynamicCall,
+  kDirectCallViaDynamicForwarder,
 }
 
 String constantTagToString(ConstantTag tag) =>
@@ -204,6 +212,8 @@
         return new ConstantInstantiatedInterfaceCall.read(reader);
       case ConstantTag.kDynamicCall:
         return new ConstantDynamicCall.read(reader);
+      case ConstantTag.kDirectCallViaDynamicForwarder:
+        return new ConstantDirectCallViaDynamicForwarder.read(reader);
       // Make analyzer happy.
       case ConstantTag.kUnused1:
       case ConstantTag.kUnused2:
@@ -553,6 +563,41 @@
       this.argDesc == other.argDesc;
 }
 
+class ConstantDirectCallViaDynamicForwarder extends ConstantPoolEntry {
+  final ObjectHandle target;
+  final ObjectHandle argDesc;
+
+  ConstantDirectCallViaDynamicForwarder(this.target, this.argDesc);
+
+  // Reserve 1 extra slot for arguments descriptor, following target slot.
+  int get numReservedEntries => 1;
+
+  @override
+  ConstantTag get tag => ConstantTag.kDirectCallViaDynamicForwarder;
+
+  @override
+  void writeValue(BufferedWriter writer) {
+    writer.writePackedObject(target);
+    writer.writePackedObject(argDesc);
+  }
+
+  ConstantDirectCallViaDynamicForwarder.read(BufferedReader reader)
+      : target = reader.readPackedObject(),
+        argDesc = reader.readPackedObject();
+
+  @override
+  String toString() => "DirectCallViaDynamicForwarder '$target', $argDesc";
+
+  @override
+  int get hashCode => _combineHashes(target.hashCode, argDesc.hashCode);
+
+  @override
+  bool operator ==(other) =>
+      other is ConstantDirectCallViaDynamicForwarder &&
+      this.target == other.target &&
+      this.argDesc == other.argDesc;
+}
+
 class ConstantInterfaceCall extends ConstantPoolEntry {
   final ObjectHandle target;
   final ObjectHandle argDesc;
@@ -700,12 +745,15 @@
           hasReceiver: hasReceiver, isFactory: isFactory)));
 
   int addDirectCall(
-          InvocationKind invocationKind, Member target, ObjectHandle argDesc) =>
-      _add(new ConstantDirectCall(
-          objectTable.getMemberHandle(target,
-              isGetter: invocationKind == InvocationKind.getter,
-              isSetter: invocationKind == InvocationKind.setter),
-          argDesc));
+      InvocationKind invocationKind, Member target, ObjectHandle argDesc,
+      [bool isDynamicForwarder = false]) {
+    final targetHandle = objectTable.getMemberHandle(target,
+        isGetter: invocationKind == InvocationKind.getter,
+        isSetter: invocationKind == InvocationKind.setter);
+    return _add(isDynamicForwarder
+        ? new ConstantDirectCallViaDynamicForwarder(targetHandle, argDesc)
+        : new ConstantDirectCall(targetHandle, argDesc));
+  }
 
   int addInterfaceCall(
           InvocationKind invocationKind, Member target, ObjectHandle argDesc) =>
@@ -772,6 +820,11 @@
   int addObjectRef(Node node) =>
       _add(new ConstantObjectRef(objectTable.getHandle(node)));
 
+  int addSelectorName(Name name, InvocationKind invocationKind) =>
+      _add(new ConstantObjectRef(objectTable.getSelectorNameHandle(name,
+          isGetter: invocationKind == InvocationKind.getter,
+          isSetter: invocationKind == InvocationKind.setter)));
+
   int _add(ConstantPoolEntry entry) {
     return _canonicalizationCache.putIfAbsent(entry, () {
       int index = entries.length;
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 790b10b6..6005219 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,7 +10,7 @@
 /// Before bumping current bytecode version format, make sure that
 /// all users have switched to a VM which is able to consume new
 /// version of bytecode.
-const int currentBytecodeFormatVersion = 20;
+const int currentBytecodeFormatVersion = 21;
 
 enum Opcode {
   kUnusedOpcode000,
@@ -210,8 +210,8 @@
   // Calls.
   kDirectCall,
   kDirectCall_Wide,
-  kUnused21, // Reserved for DirectCall1
-  kUnused22, // Reserved for DirectCall1_Wide
+  kUncheckedDirectCall,
+  kUncheckedDirectCall_Wide,
   kInterfaceCall,
   kInterfaceCall_Wide,
   kUnused23, // Reserved for InterfaceCall1
@@ -258,8 +258,8 @@
 
   // Null operations.
   kEqualsNull,
-  kUnused36, // Reserved for CheckNull
-  kUnused37, // Reserved for CheckNull_Wide
+  kCheckReceiverForNull,
+  kCheckReceiverForNull_Wide,
 
   // Int operations.
   kNegateInt,
@@ -468,6 +468,8 @@
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kEqualsNull: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+  Opcode.kCheckReceiverForNull: const Format(
+      Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kNegateInt: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kAddInt: const Format(
@@ -502,6 +504,8 @@
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kDirectCall: const Format(
       Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
+  Opcode.kUncheckedDirectCall: const Format(
+      Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
   Opcode.kAllocateClosure: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kUncheckedClosureCall: const Format(
@@ -608,6 +612,7 @@
 bool isCall(Opcode opcode) {
   switch (opcode) {
     case Opcode.kDirectCall:
+    case Opcode.kUncheckedDirectCall:
     case Opcode.kInterfaceCall:
     case Opcode.kInstantiatedInterfaceCall:
     case Opcode.kUncheckedClosureCall:
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 5303161..9f80ff9 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -23,7 +23,8 @@
     show globalDebuggingNames, NameSystem;
 import 'package:kernel/type_algebra.dart'
     show Substitution, containsTypeVariable;
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+    show SubtypeCheckMode, TypeEnvironment;
 import 'assembler.dart';
 import 'bytecode_serialization.dart' show StringTable;
 import 'constant_pool.dart';
@@ -53,8 +54,11 @@
 import 'recursive_types_validator.dart' show IllegalRecursiveTypeException;
 import 'source_positions.dart' show LineStarts, SourcePositions;
 import '../metadata/bytecode.dart';
+import '../metadata/direct_call.dart'
+    show DirectCallMetadata, DirectCallMetadataRepository;
 
 import 'dart:convert' show utf8;
+import 'dart:developer';
 import 'dart:math' as math;
 
 // This symbol is used as the name in assert assignable's to indicate it comes
@@ -69,37 +73,39 @@
   CoreTypes coreTypes,
   ClassHierarchy hierarchy,
 }) {
-  options ??= new BytecodeOptions();
-  verifyBytecodeInstructionDeclarations();
-  coreTypes ??= new CoreTypes(component);
-  void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
-  hierarchy ??= new ClassHierarchy(component,
-      onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
-  final typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
-  libraries ??= component.libraries;
+  Timeline.timeSync("generateBytecode", () {
+    options ??= new BytecodeOptions();
+    verifyBytecodeInstructionDeclarations();
+    coreTypes ??= new CoreTypes(component);
+    void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
+    hierarchy ??= new ClassHierarchy(component,
+        onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+    final typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
+    libraries ??= component.libraries;
 
-  // Save/restore global NameSystem to avoid accumulating garbage.
-  // NameSystem holds the whole AST as it is strongly connected due to
-  // parent pointers. Objects are added to NameSystem when toString()
-  // is called from AST nodes.  Bytecode generator widely uses
-  // Expression.getStaticType, which calls Expression.getStaticTypeAsInstanceOf,
-  // which uses toString() when it crashes due to http://dartbug.com/34496.
-  final savedGlobalDebuggingNames = globalDebuggingNames;
-  globalDebuggingNames = new NameSystem();
+    // Save/restore global NameSystem to avoid accumulating garbage.
+    // NameSystem holds the whole AST as it is strongly connected due to
+    // parent pointers. Objects are added to NameSystem when toString()
+    // is called from AST nodes.  Bytecode generator widely uses
+    // Expression.getStaticType, which calls Expression.getStaticTypeAsInstanceOf,
+    // which uses toString() when it crashes due to http://dartbug.com/34496.
+    final savedGlobalDebuggingNames = globalDebuggingNames;
+    globalDebuggingNames = new NameSystem();
 
-  try {
-    final bytecodeGenerator = new BytecodeGenerator(
-        component, coreTypes, hierarchy, typeEnvironment, options);
-    for (var library in libraries) {
-      bytecodeGenerator.visitLibrary(library);
+    try {
+      final bytecodeGenerator = new BytecodeGenerator(
+          component, coreTypes, hierarchy, typeEnvironment, options);
+      for (var library in libraries) {
+        bytecodeGenerator.visitLibrary(library);
+      }
+    } on IllegalRecursiveTypeException catch (e) {
+      CompilerContext.current.options.report(
+          templateIllegalRecursiveType.withArguments(e.type).withoutLocation(),
+          Severity.error);
+    } finally {
+      globalDebuggingNames = savedGlobalDebuggingNames;
     }
-  } on IllegalRecursiveTypeException catch (e) {
-    CompilerContext.current.options.report(
-        templateIllegalRecursiveType.withArguments(e.type).withoutLocation(),
-        Severity.error);
-  } finally {
-    globalDebuggingNames = savedGlobalDebuggingNames;
-  }
+  });
 }
 
 class BytecodeGenerator extends RecursiveVisitor<Null> {
@@ -115,6 +121,7 @@
   ObjectTable objectTable;
   Component bytecodeComponent;
   NullabilityDetector nullabilityDetector;
+  Map<TreeNode, DirectCallMetadata> directCallMetadata;
 
   List<ClassDeclaration> classDeclarations;
   List<FieldDeclaration> fieldDeclarations;
@@ -165,6 +172,9 @@
       bytecodeComponent.mainLibrary =
           objectTable.getHandle(component.mainMethod.enclosingLibrary);
     }
+
+    directCallMetadata =
+        component.metadata[DirectCallMetadataRepository.repositoryTag]?.mapping;
   }
 
   @override
@@ -1132,21 +1142,32 @@
   }
 
   void _genDirectCall(Member target, ObjectHandle argDesc, int totalArgCount,
-      {bool isGet: false, bool isSet: false, TreeNode context}) {
+      {bool isGet: false,
+      bool isSet: false,
+      bool isDynamicForwarder: false,
+      bool isUnchecked: false,
+      TreeNode context}) {
     assert(!isGet || !isSet);
     final kind = isGet
         ? InvocationKind.getter
         : (isSet ? InvocationKind.setter : InvocationKind.method);
-    final cpIndex = cp.addDirectCall(kind, target, argDesc);
+    final cpIndex = cp.addDirectCall(kind, target, argDesc, isDynamicForwarder);
 
     if (totalArgCount >= argumentsLimit) {
       throw new TooManyArgumentsException(context.fileOffset);
     }
-    asm.emitDirectCall(cpIndex, totalArgCount);
+    if (isUnchecked) {
+      asm.emitUncheckedDirectCall(cpIndex, totalArgCount);
+    } else {
+      asm.emitDirectCall(cpIndex, totalArgCount);
+    }
   }
 
   void _genDirectCallWithArgs(Member target, Arguments args,
-      {bool hasReceiver: false, bool isFactory: false, TreeNode context}) {
+      {bool hasReceiver: false,
+      bool isFactory: false,
+      bool isUnchecked: false,
+      TreeNode context}) {
     final argDesc = objectTable.getArgDescHandleByArguments(args,
         hasReceiver: hasReceiver, isFactory: isFactory);
 
@@ -1160,7 +1181,8 @@
       totalArgCount++;
     }
 
-    _genDirectCall(target, argDesc, totalArgCount, context: context);
+    _genDirectCall(target, argDesc, totalArgCount,
+        isUnchecked: isUnchecked, context: context);
   }
 
   void _genTypeArguments(List<DartType> typeArgs, {Class instantiatingClass}) {
@@ -1514,7 +1536,8 @@
     savedMaxSourcePositions = <int>[];
     maxSourcePosition = node.fileOffset;
 
-    locals = new LocalVariables(node, options, typeEnvironment);
+    locals =
+        new LocalVariables(node, options, typeEnvironment, directCallMetadata);
     locals.enterScope(node);
     assert(!locals.isSyncYieldingFrame);
 
@@ -2140,7 +2163,9 @@
     _genPushInstantiatorAndFunctionTypeArguments([type]);
     asm.emitPushConstant(cp.addString(name));
     bool isIntOk = typeEnvironment.isSubtypeOf(
-        typeEnvironment.coreTypes.intLegacyRawType, type);
+        typeEnvironment.coreTypes.intLegacyRawType,
+        type,
+        SubtypeCheckMode.ignoringNullabilities);
     int subtypeTestCacheCpIndex = cp.addSubtypeTestCache();
     asm.emitAssertAssignable(isIntOk ? 1 : 0, subtypeTestCacheCpIndex);
   }
@@ -3020,27 +3045,62 @@
       return;
     }
 
-    _genArguments(node.receiver, args);
+    final directCall =
+        directCallMetadata != null ? directCallMetadata[node] : null;
+    if (directCall != null && directCall.checkReceiverForNull) {
+      final int receiverTemp = locals.tempIndexInFrame(node);
+      _genArguments(node.receiver, args, storeReceiverToLocal: receiverTemp);
+      asm.emitPush(receiverTemp);
+      asm.emitCheckReceiverForNull(
+          cp.addSelectorName(node.name, InvocationKind.method));
+    } else {
+      _genArguments(node.receiver, args);
+    }
 
     Member interfaceTarget = node.interfaceTarget;
     if (interfaceTarget is Field ||
         interfaceTarget is Procedure && interfaceTarget.isGetter) {
       // Call via field or getter. Treat it as a dynamic call because
       // interface target doesn't fully represent what is being called.
+      assert(directCall == null);
       interfaceTarget = null;
     }
+
     final argDesc =
         objectTable.getArgDescHandleByArguments(args, hasReceiver: true);
-    _genInstanceCall(InvocationKind.method, interfaceTarget, node.name,
-        node.receiver, totalArgCount, argDesc);
+
+    if (directCall != null) {
+      final isDynamicForwarder = (interfaceTarget == null);
+      final isUnchecked =
+          isUncheckedCall(interfaceTarget, node.receiver, typeEnvironment);
+      _genDirectCall(directCall.target, argDesc, totalArgCount,
+          isDynamicForwarder: isDynamicForwarder, isUnchecked: isUnchecked);
+    } else {
+      _genInstanceCall(InvocationKind.method, interfaceTarget, node.name,
+          node.receiver, totalArgCount, argDesc);
+    }
   }
 
   @override
   visitPropertyGet(PropertyGet node) {
     _generateNode(node.receiver);
     final argDesc = objectTable.getArgDescHandle(1);
-    _genInstanceCall(InvocationKind.getter, node.interfaceTarget, node.name,
-        node.receiver, 1, argDesc);
+
+    final directCall =
+        directCallMetadata != null ? directCallMetadata[node] : null;
+    if (directCall != null) {
+      if (directCall.checkReceiverForNull) {
+        final int receiverTemp = locals.tempIndexInFrame(node);
+        asm.emitStoreLocal(receiverTemp);
+        asm.emitPush(receiverTemp);
+        asm.emitCheckReceiverForNull(
+            cp.addSelectorName(node.name, InvocationKind.getter));
+      }
+      _genDirectCall(directCall.target, argDesc, 1, isGet: true);
+    } else {
+      _genInstanceCall(InvocationKind.getter, node.interfaceTarget, node.name,
+          node.receiver, 1, argDesc);
+    }
   }
 
   @override
@@ -3049,15 +3109,38 @@
     final bool hasResult = !isExpressionWithoutResult(node);
 
     _generateNode(node.receiver);
-    _generateNode(node.value);
+
+    final directCall =
+        directCallMetadata != null ? directCallMetadata[node] : null;
+    if (directCall != null && directCall.checkReceiverForNull) {
+      asm.emitStoreLocal(temp);
+      _generateNode(node.value);
+      asm.emitPush(temp);
+      asm.emitCheckReceiverForNull(
+          cp.addSelectorName(node.name, InvocationKind.setter));
+    } else {
+      _generateNode(node.value);
+    }
 
     if (hasResult) {
       asm.emitStoreLocal(temp);
     }
 
-    final argDesc = objectTable.getArgDescHandle(2);
-    _genInstanceCall(InvocationKind.setter, node.interfaceTarget, node.name,
-        node.receiver, 2, argDesc);
+    const int numArguments = 2;
+    final argDesc = objectTable.getArgDescHandle(numArguments);
+
+    if (directCall != null) {
+      final isDynamicForwarder = (node.interfaceTarget == null);
+      final isUnchecked =
+          isUncheckedCall(node.interfaceTarget, node.receiver, typeEnvironment);
+      _genDirectCall(directCall.target, argDesc, numArguments,
+          isSet: true,
+          isDynamicForwarder: isDynamicForwarder,
+          isUnchecked: isUnchecked);
+    } else {
+      _genInstanceCall(InvocationKind.setter, node.interfaceTarget, node.name,
+          node.receiver, numArguments, argDesc);
+    }
 
     asm.emitDrop1();
 
@@ -3084,7 +3167,8 @@
       return;
     }
     _genArguments(new ThisExpression(), args);
-    _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
+    _genDirectCallWithArgs(target, args,
+        hasReceiver: true, isUnchecked: true, context: node);
   }
 
   @override
@@ -3121,7 +3205,8 @@
       }
 
       assert(target is Field || (target is Procedure && target.isSetter));
-      _genDirectCall(target, objectTable.getArgDescHandle(2), 2, isSet: true);
+      _genDirectCall(target, objectTable.getArgDescHandle(2), 2,
+          isSet: true, isUnchecked: true);
     }
 
     asm.emitDrop1();
@@ -3955,6 +4040,7 @@
     }
 
     final TryBlock tryBlock = _startTryBlock(node);
+    tryBlock.isSynthetic = true;
     finallyBlocks[node] = <FinallyBlock>[];
 
     _generateNode(node.body);
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index 4176254..6421694 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -14,6 +14,7 @@
 
 import 'dbc.dart';
 import 'options.dart' show BytecodeOptions;
+import '../metadata/direct_call.dart' show DirectCallMetadata;
 
 class LocalVariables {
   final Map<TreeNode, Scope> _scopes = <TreeNode, Scope>{};
@@ -30,6 +31,7 @@
       <ForInStatement, VariableDeclaration>{};
   final BytecodeOptions options;
   final TypeEnvironment typeEnvironment;
+  final Map<TreeNode, DirectCallMetadata> directCallMetadata;
 
   Scope _currentScope;
   Frame _currentFrame;
@@ -191,7 +193,8 @@
   List<VariableDeclaration> get sortedNamedParameters =>
       _currentFrame.sortedNamedParameters;
 
-  LocalVariables(Member node, this.options, this.typeEnvironment) {
+  LocalVariables(Member node, this.options, this.typeEnvironment,
+      this.directCallMetadata) {
     final scopeBuilder = new _ScopeBuilder(this);
     node.accept(scopeBuilder);
 
@@ -1210,6 +1213,11 @@
     int numTemps = 0;
     if (isUncheckedClosureCall(node, locals.typeEnvironment, locals.options)) {
       numTemps = 1;
+    } else if (locals.directCallMetadata != null) {
+      final directCall = locals.directCallMetadata[node];
+      if (directCall != null && directCall.checkReceiverForNull) {
+        numTemps = 1;
+      }
     }
     _visit(node, temps: numTemps);
   }
@@ -1220,6 +1228,18 @@
   }
 
   @override
+  visitPropertyGet(PropertyGet node) {
+    int numTemps = 0;
+    if (locals.directCallMetadata != null) {
+      final directCall = locals.directCallMetadata[node];
+      if (directCall != null && directCall.checkReceiverForNull) {
+        numTemps = 1;
+      }
+    }
+    _visit(node, temps: numTemps);
+  }
+
+  @override
   visitDirectPropertySet(DirectPropertySet node) {
     _visit(node, temps: 1);
   }
diff --git a/pkg/vm/lib/bytecode/object_table.dart b/pkg/vm/lib/bytecode/object_table.dart
index 57452d0..4170bbb 100644
--- a/pkg/vm/lib/bytecode/object_table.dart
+++ b/pkg/vm/lib/bytecode/object_table.dart
@@ -1705,7 +1705,6 @@
     } else {
       throw "Unexpected Member's parent ${parent.runtimeType} $parent";
     }
-    if (member is Constructor || member is Procedure && member.isFactory) {}
     final nameHandle = getNameHandle(
         member.name.library, mangleMemberName(member, isGetter, isSetter));
     bool isField = member is Field && !isGetter && !isSetter;
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index f215187..4329c60 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -25,6 +25,9 @@
 import 'package:path/path.dart' as path;
 import 'package:usage/uuid/uuid.dart';
 
+import 'package:vm/metadata/binary_cache.dart'
+    show BinaryCacheMetadataRepository;
+
 import 'package:vm/bytecode/gen_bytecode.dart'
     show generateBytecode, createFreshComponentWithBytecode;
 import 'package:vm/bytecode/options.dart' show BytecodeOptions;
@@ -41,6 +44,7 @@
         parseCommandLineDefines,
         runWithFrontEndCompilerContext,
         setVMEnvironmentDefines,
+        sortComponent,
         writeDepfile;
 
 ArgParser argParser = new ArgParser(allowTrailingOptions: true)
@@ -363,22 +367,29 @@
       ];
     }
 
+    if (compilerOptions.bytecode && _initializeFromDill != null) {
+      // If we are generating bytecode, put bytecode only (not AST) in
+      // [_kernelBinaryFilename], which the user of this tool will eventually
+      // feed to Flutter engine or flutter_tester. Use a separate file to cache
+      // the AST result to initialize the incremental compiler for the next
+      // invocation of this tool.
+      _initializeFromDill += ".ast";
+    }
+
+    _compilerOptions = compilerOptions;
+    _bytecodeOptions = bytecodeOptions;
+
     Component component;
     Iterable<Uri> compiledSources;
     if (options['incremental']) {
-      _compilerOptions = compilerOptions;
-      _bytecodeOptions = bytecodeOptions;
       setVMEnvironmentDefines(environmentDefines, _compilerOptions);
 
       _compilerOptions.omitPlatform = false;
       _generator =
           generator ?? _createGenerator(new Uri.file(_initializeFromDill));
       await invalidateIfInitializingFromDill();
-      component = await _runWithPrintRedirection(() async {
-        final c = await _generator.compile();
-        compiledSources = c.uriToSource.keys;
-        return await _generateBytecodeIfNeeded(c);
-      });
+      component = await _runWithPrintRedirection(() => _generator.compile());
+      compiledSources = component.uriToSource.keys;
     } else {
       if (options['link-platform']) {
         // TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -471,28 +482,67 @@
 
   writeDillFile(Component component, String filename,
       {bool filterExternal: false}) async {
-    final IOSink sink = new File(filename).openWrite();
-    final BinaryPrinter printer = filterExternal
-        ? new LimitedBinaryPrinter(
-            sink, (lib) => !lib.isExternal, true /* excludeUriToSource */)
-        : printerFactory.newBinaryPrinter(sink);
+    // Remove the cache that came either from this function or from
+    // initializing from a kernel file.
+    component.metadata.remove(BinaryCacheMetadataRepository.repositoryTag);
 
-    component.libraries.sort((Library l1, Library l2) {
-      return "${l1.fileUri}".compareTo("${l2.fileUri}");
-    });
+    if (_compilerOptions.bytecode) {
+      {
+        // Generate bytecode as the output proper.
+        final IOSink sink = new File(filename).openWrite();
+        await runWithFrontEndCompilerContext(
+            _mainSource, _compilerOptions, component, () async {
+          if (_options['incremental']) {
+            await forEachPackage(component,
+                (String package, List<Library> libraries) async {
+              _writePackage(component, package, libraries, sink);
+            });
+          } else {
+            _writePackage(component, 'main', component.libraries, sink);
+          }
+        });
+        await sink.close();
+      }
 
-    component.computeCanonicalNames();
-    for (Library library in component.libraries) {
-      library.additionalExports.sort((Reference r1, Reference r2) {
-        return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
-      });
+      {
+        // Generate AST as a cache.
+        final repository = new BinaryCacheMetadataRepository();
+        component.addMetadataRepository(repository);
+        for (var lib in component.libraries) {
+          var bytes = BinaryCacheMetadataRepository.lookup(lib);
+          if (bytes != null) {
+            repository.mapping[lib] = bytes;
+          }
+        }
+
+        final IOSink sink = new File(filename + ".ast").openWrite();
+        final BinaryPrinter printer = filterExternal
+            ? new LimitedBinaryPrinter(
+                sink, (lib) => !lib.isExternal, true /* excludeUriToSource */)
+            : printerFactory.newBinaryPrinter(sink);
+
+        sortComponent(component);
+
+        printer.writeComponentFile(component);
+        await sink.close();
+      }
+    } else {
+      // Generate AST as the output proper.
+      final IOSink sink = new File(filename).openWrite();
+      final BinaryPrinter printer = filterExternal
+          ? new LimitedBinaryPrinter(
+              sink, (lib) => !lib.isExternal, true /* excludeUriToSource */)
+          : printerFactory.newBinaryPrinter(sink);
+
+      sortComponent(component);
+
+      if (unsafePackageSerialization == true) {
+        writePackagesToSinkAndTrimComponent(component, sink);
+      }
+
+      printer.writeComponentFile(component);
+      await sink.close();
     }
-    if (unsafePackageSerialization == true) {
-      writePackagesToSinkAndTrimComponent(component, sink);
-    }
-
-    printer.writeComponentFile(component);
-    await sink.close();
   }
 
   Future<Null> invalidateIfInitializingFromDill() async {
@@ -552,17 +602,6 @@
     }
   }
 
-  bool _elementsIdentical(List a, List b) {
-    if (a.length != b.length) return false;
-    for (int i = 0; i < a.length; i++) {
-      if (!identical(a[i], b[i])) return false;
-    }
-    return true;
-  }
-
-  final _packageLibraries = new Expando();
-  final _packageBytes = new Expando();
-
   void _writePackage(Component component, String package,
       List<Library> libraries, IOSink sink) {
     final canCache = libraries.isNotEmpty &&
@@ -571,10 +610,9 @@
         package != "main";
 
     if (canCache) {
-      var cachedLibraries = _packageLibraries[libraries.first];
-      if ((cachedLibraries != null) &&
-          _elementsIdentical(cachedLibraries, libraries)) {
-        sink.add(_packageBytes[libraries.first]);
+      var cachedBytes = BinaryCacheMetadataRepository.lookup(libraries.first);
+      if (cachedBytes != null) {
+        sink.add(cachedBytes);
         return;
       }
     }
@@ -600,8 +638,7 @@
     final bytes = byteSink.builder.takeBytes();
     sink.add(bytes);
     if (canCache) {
-      _packageLibraries[libraries.first] = libraries;
-      _packageBytes[libraries.first] = bytes;
+      BinaryCacheMetadataRepository.insert(libraries.first, bytes);
     }
   }
 
@@ -621,19 +658,7 @@
     }
     final compiledSources = deltaProgram.uriToSource.keys;
 
-    if (_compilerOptions.bytecode) {
-      final IOSink sink = new File(_kernelBinaryFilename).openWrite();
-      await runWithFrontEndCompilerContext(
-          _mainSource, _compilerOptions, deltaProgram, () async {
-        await forEachPackage(deltaProgram,
-            (String package, List<Library> libraries) async {
-          _writePackage(deltaProgram, package, libraries, sink);
-        });
-      });
-      await sink.close();
-    } else {
-      await writeDillFile(deltaProgram, _kernelBinaryFilename);
-    }
+    await writeDillFile(deltaProgram, _kernelBinaryFilename);
 
     _outputStream.writeln(boundaryKey);
     await _outputDependenciesDelta(compiledSources);
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index d66c022..765991b 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -5,6 +5,7 @@
 /// Defines wrapper class around incremental compiler to support
 /// the flow, where incremental deltas can be rejected by VM.
 import 'dart:async';
+import 'dart:developer';
 
 import 'package:front_end/src/api_unstable/vm.dart';
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -44,15 +45,21 @@
   /// If [entryPoint] is specified, that points to new entry point for the
   /// compilation. Otherwise, previously set entryPoint is used.
   Future<Component> compile({Uri entryPoint}) async {
-    _entryPoint = entryPoint ?? _entryPoint;
-    List<Uri> entryPoints;
-    if (entryPoint != null) entryPoints = [entryPoint];
-    Component component = await _generator.computeDelta(
-        entryPoints: entryPoints, fullComponent: fullComponent);
-    initialized = true;
-    fullComponent = false;
-    _pendingDeltas.add(component);
-    return _combinePendingDeltas(false);
+    final task = new TimelineTask();
+    try {
+      task.start("IncrementalCompiler.compile");
+      _entryPoint = entryPoint ?? _entryPoint;
+      List<Uri> entryPoints;
+      if (entryPoint != null) entryPoints = [entryPoint];
+      Component component = await _generator.computeDelta(
+          entryPoints: entryPoints, fullComponent: fullComponent);
+      initialized = true;
+      fullComponent = false;
+      _pendingDeltas.add(component);
+      return _combinePendingDeltas(false);
+    } finally {
+      task.finish();
+    }
   }
 
   _combinePendingDeltas(bool includePlatform) {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 1a633c6..3e2bd46 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -660,10 +660,10 @@
   return 'main';
 }
 
-Future<Null> forEachPackage<T>(Component component,
-    T action(String package, List<Library> libraries)) async {
-  // Package sharing: make the encoding not depend on the order in which parts
-  // of a package are loaded.
+/// Sort the libraries etc in the component. Helps packages to produce identical
+/// output when their parts are imported in different orders in different
+/// contexts.
+void sortComponent(Component component) {
   component.libraries.sort((Library a, Library b) {
     return a.importUri.toString().compareTo(b.importUri.toString());
   });
@@ -673,6 +673,11 @@
       return a.canonicalName.toString().compareTo(b.canonicalName.toString());
     });
   }
+}
+
+Future<Null> forEachPackage<T>(Component component,
+    T action(String package, List<Library> libraries)) async {
+  sortComponent(component);
 
   final packages = new Map<String, List<Library>>();
   for (Library lib in component.libraries) {
diff --git a/pkg/vm/lib/metadata/binary_cache.dart b/pkg/vm/lib/metadata/binary_cache.dart
new file mode 100644
index 0000000..e2151ef
--- /dev/null
+++ b/pkg/vm/lib/metadata/binary_cache.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.metadata.binary_cache;
+
+import 'package:kernel/ast.dart'
+    show BinarySink, BinarySource, MetadataRepository, Node, TreeNode;
+
+class BinaryCacheMetadataRepository extends MetadataRepository<List<int>> {
+  static const repositoryTag = 'vm.binary_cache';
+
+  @override
+  String get tag => repositoryTag;
+
+  @override
+  final Map<TreeNode, List<int>> mapping = <TreeNode, List<int>>{};
+
+  @override
+  void writeToBinary(List<int> metadata, Node node, BinarySink sink) {
+    sink.writeByteList(metadata);
+  }
+
+  @override
+  List<int> readFromBinary(Node node, BinarySource source) {
+    List<int> result = source.readByteList();
+    _weakMap[node] = result;
+    return result;
+  }
+
+  static List<int> lookup(Node node) => _weakMap[node];
+  static void insert(Node node, List<int> metadata) {
+    _weakMap[node] = metadata;
+  }
+
+  static final _weakMap = new Expando<List<int>>();
+}
diff --git a/pkg/vm/lib/metadata/bytecode.dart b/pkg/vm/lib/metadata/bytecode.dart
index 97e250c..15781bd 100644
--- a/pkg/vm/lib/metadata/bytecode.dart
+++ b/pkg/vm/lib/metadata/bytecode.dart
@@ -10,17 +10,23 @@
     show BufferedWriter, BufferedReader, LinkWriter, LinkReader;
 import '../bytecode/declarations.dart' show Component;
 
+import 'dart:developer';
+
 class BytecodeMetadata {
   final Component component;
 
   BytecodeMetadata(this.component);
 
   void write(BufferedWriter writer) {
-    component.write(writer);
+    Timeline.timeSync("BytecodeMetadata.write", () {
+      component.write(writer);
+    });
   }
 
   factory BytecodeMetadata.read(BufferedReader reader) {
-    return new BytecodeMetadata(new Component.read(reader));
+    return Timeline.timeSync("BytecodeMetadata.read", () {
+      return new BytecodeMetadata(new Component.read(reader));
+    });
   }
 
   @override
@@ -62,3 +68,32 @@
     return new BytecodeMetadata(bytecodeComponent);
   }
 }
+
+class BinaryCacheMetadataRepository extends MetadataRepository<List<int>> {
+  static const repositoryTag = 'vm.bytecode.cache';
+
+  @override
+  String get tag => repositoryTag;
+
+  @override
+  final Map<TreeNode, List<int>> mapping = <TreeNode, List<int>>{};
+
+  @override
+  void writeToBinary(List<int> metadata, Node node, BinarySink sink) {
+    sink.writeByteList(metadata);
+  }
+
+  @override
+  List<int> readFromBinary(Node node, BinarySource source) {
+    List<int> result = source.readByteList();
+    _weakMap[node] = result;
+    return result;
+  }
+
+  static List<int> lookup(Node node) => _weakMap[node];
+  static void insert(Node node, List<int> metadata) {
+    _weakMap[node] = metadata;
+  }
+
+  static final _weakMap = new Expando<List<int>>();
+}
diff --git a/pkg/vm/lib/metadata/direct_call.dart b/pkg/vm/lib/metadata/direct_call.dart
index 9c2594e..fcb9f32 100644
--- a/pkg/vm/lib/metadata/direct_call.dart
+++ b/pkg/vm/lib/metadata/direct_call.dart
@@ -26,8 +26,10 @@
 /// Repository for [DirectCallMetadata].
 class DirectCallMetadataRepository
     extends MetadataRepository<DirectCallMetadata> {
+  static const repositoryTag = 'vm.direct-call.metadata';
+
   @override
-  final String tag = 'vm.direct-call.metadata';
+  String get tag => repositoryTag;
 
   @override
   final Map<TreeNode, DirectCallMetadata> mapping =
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index eefc73c..a647eb8 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -17,6 +17,7 @@
 import 'package:kernel/vm/constants_native_effects.dart'
     show VmConstantsBackend;
 
+import '../metadata/binary_cache.dart' show BinaryCacheMetadataRepository;
 import '../transformations/call_site_annotator.dart' as callSiteAnnotator;
 import '../transformations/list_factory_specializer.dart'
     as listFactorySpecializer;
@@ -114,6 +115,8 @@
         // need to index dart:collection, as it is only needed for desugaring of
         // const sets. We can remove it from this list at that time.
         "dart:collection",
+        // The bytecode pipeline uses the index to check if dart:ffi is used.
+        "dart:ffi",
         // TODO(askesc): This is for the VM host endian optimization, which
         // could possibly be done more cleanly after the VM no longer supports
         // doing constant evaluation on its own. See http://dartbug.com/32836
@@ -367,6 +370,7 @@
   @override
   Component configureComponent(Component component) {
     callSiteAnnotator.addRepositoryTo(component);
+    component.addMetadataRepository(new BinaryCacheMetadataRepository());
     return super.configureComponent(component);
   }
 
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 0765dd5..412b135 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -20,6 +20,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/library_index.dart' show LibraryIndex;
 import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
 
 import 'ffi.dart';
 
@@ -142,7 +143,8 @@
     return env.isSubtypeOf(
         field.type,
         InterfaceType(pointerClass,
-            [InterfaceType(nativeTypesClasses[NativeType.kNativeType.index])]));
+            [InterfaceType(nativeTypesClasses[NativeType.kNativeType.index])]),
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   bool _checkFieldAnnotations(Class node) {
@@ -178,7 +180,8 @@
         final DartType shouldBeDartType =
             convertNativeTypeToDartType(nativeType, /*allowStructs=*/ false);
         if (shouldBeDartType == null ||
-            !env.isSubtypeOf(dartType, shouldBeDartType)) {
+            !env.isSubtypeOf(dartType, shouldBeDartType,
+                SubtypeCheckMode.ignoringNullabilities)) {
           diagnosticReporter.report(
               templateFfiTypeMismatch.withArguments(
                   dartType, shouldBeDartType, nativeType),
@@ -426,20 +429,13 @@
   }
 
   Iterable<NativeType> _getNativeTypeAnnotations(Field node) {
-    final Iterable<NativeType> preConstant2018 = node.annotations
-        .whereType<ConstructorInvocation>()
-        .map((expr) => expr.target.parent)
-        .map((klass) => _getFieldType(klass))
-        .where((type) => type != null);
-    final Iterable<NativeType> postConstant2018 = node.annotations
+    return node.annotations
         .whereType<ConstantExpression>()
         .map((expr) => expr.constant)
         .whereType<InstanceConstant>()
         .map((constant) => constant.classNode)
         .map((klass) => _getFieldType(klass))
         .where((type) => type != null);
-    // TODO(dacoharkes): Remove preConstant2018 after constants change landed.
-    return postConstant2018.followedBy(preConstant2018);
   }
 }
 
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 0083c57..d3fd73b 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -22,6 +22,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/library_index.dart' show LibraryIndex;
 import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+import 'package:kernel/type_environment.dart';
 
 import 'ffi.dart'
     show
@@ -196,7 +197,8 @@
 
           final DartType returnType = exceptionalReturn.getStaticType(env);
 
-          if (!env.isSubtypeOf(returnType, funcType.returnType)) {
+          if (!env.isSubtypeOf(returnType, funcType.returnType,
+              SubtypeCheckMode.ignoringNullabilities)) {
             diagnosticReporter.report(
                 templateFfiDartTypeMismatch.withArguments(
                     returnType, funcType.returnType),
@@ -360,8 +362,10 @@
         convertNativeTypeToDartType(containerTypeArg, allowStructs);
     if (elementType == shouldBeElementType) return;
     // Both subtypes and implicit downcasts are allowed statically.
-    if (env.isSubtypeOf(shouldBeElementType, elementType)) return;
-    if (env.isSubtypeOf(elementType, shouldBeElementType)) return;
+    if (env.isSubtypeOf(shouldBeElementType, elementType,
+        SubtypeCheckMode.ignoringNullabilities)) return;
+    if (env.isSubtypeOf(elementType, shouldBeElementType,
+        SubtypeCheckMode.ignoringNullabilities)) return;
     diagnosticReporter.report(
         templateFfiTypeMismatch.withArguments(
             elementType, shouldBeElementType, containerTypeArg),
@@ -409,8 +413,8 @@
       return false;
     }
     final Class nativeClass = (nativeType as InterfaceType).classNode;
-    if (env.isSubtypeOf(
-        InterfaceType(nativeClass), InterfaceType(pointerClass))) {
+    if (env.isSubtypeOf(InterfaceType(nativeClass), InterfaceType(pointerClass),
+        SubtypeCheckMode.ignoringNullabilities)) {
       return true;
     }
     if (hierarchy.isSubclassOf(nativeClass, structClass)) {
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index 32781bb..7d346c0 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -123,7 +123,7 @@
   Push                 FP[-6]
   PushConstant         CP#1
   PushInt              2
-  DirectCall           CP#2, 4
+  UncheckedDirectCall  CP#2, 4
   ReturnTOS
 }
 ConstantPool {
@@ -201,7 +201,7 @@
   CheckStack           0
   Push                 FP[-5]
   PushInt              3
-  DirectCall           CP#0, 2
+  UncheckedDirectCall  CP#0, 2
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index 47fd310..da56542 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -579,7 +579,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 19, end 36, handler 36, needs-stack-trace, types [CP#0]
+  try-index 0, outer -1, start 19, end 36, handler 36, needs-stack-trace, synthetic, types [CP#0]
 }
 ConstantPool {
   [0] = Type dynamic
@@ -702,8 +702,8 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 53, end 162, handler 162, needs-stack-trace, types [CP#20]
-  try-index 1, outer 0, start 70, end 124, handler 124, needs-stack-trace, types [CP#20]
+  try-index 0, outer -1, start 53, end 162, handler 162, needs-stack-trace, synthetic, types [CP#20]
+  try-index 1, outer 0, start 70, end 124, handler 124, needs-stack-trace, synthetic, types [CP#20]
 }
 ConstantPool {
   [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
@@ -822,7 +822,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 23, end 61, handler 61, needs-stack-trace, types [CP#6]
+  try-index 0, outer -1, start 23, end 61, handler 61, needs-stack-trace, synthetic, types [CP#6]
 }
 ConstantPool {
   [0] = ClosureFunction 0
@@ -982,7 +982,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 4, end 40, handler 40, needs-stack-trace, types [CP#3]
+  try-index 0, outer -1, start 4, end 40, handler 40, needs-stack-trace, synthetic, types [CP#3]
   try-index 1, outer 0, start 4, end 14, handler 14, types [CP#3]
 }
 ConstantPool {
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index de2ecc3..4ab42ff 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -645,7 +645,7 @@
   Push                 FP[-7]
   Push                 FP[-6]
   Push                 FP[-5]
-  DirectCall           CP#9, 5
+  UncheckedDirectCall  CP#9, 5
   ReturnTOS
 }
 Parameter flags: [0, 1, 2]
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index a5de560..98241e7 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,4 +1,7 @@
 # Changelog
+## 2.1.1
+- Added `getLineNumberFromTokenPos` and `getColumnNumberFromTokenPos` methods
+  to `Script`.
 
 ## 2.1.0
 - Added `HeapSnapshotGraph` class which parses the binary events posted to the
diff --git a/pkg/vm_service/lib/vm_service.dart b/pkg/vm_service/lib/vm_service.dart
index 5133141..0eeea9b 100644
--- a/pkg/vm_service/lib/vm_service.dart
+++ b/pkg/vm_service/lib/vm_service.dart
@@ -5456,6 +5456,9 @@
   static Script parse(Map<String, dynamic> json) =>
       json == null ? null : Script._fromJson(json);
 
+  final _tokenToLine = <int, int>{};
+  final _tokenToColumn = <int, int>{};
+
   /// The uri from which this script was loaded.
   String uri;
 
@@ -5496,6 +5499,34 @@
         ? null
         : List<List<int>>.from(
             json['tokenPosTable'].map((dynamic list) => List<int>.from(list)));
+    _parseTokenPosTable();
+  }
+
+  /// This function maps a token position to a line number.
+  /// The VM considers the first line to be line 1.
+  int getLineNumberFromTokenPos(int tokenPos) => _tokenToLine[tokenPos];
+
+  /// This function maps a token position to a column number.
+  /// The VM considers the first column to be column 1.
+  int getColumnNumberFromTokenPos(int tokenPos) => _tokenToColumn[tokenPos];
+
+  void _parseTokenPosTable() {
+    if (tokenPosTable == null) {
+      return;
+    }
+    final lineSet = Set<int>();
+    for (List line in tokenPosTable) {
+      // Each entry begins with a line number...
+      int lineNumber = line[0];
+      lineSet.add(lineNumber);
+      for (var pos = 1; pos < line.length; pos += 2) {
+        // ...and is followed by (token offset, col number) pairs.
+        final int tokenOffset = line[pos];
+        final int colNumber = line[pos + 1];
+        _tokenToLine[tokenOffset] = lineNumber;
+        _tokenToColumn[tokenOffset] = colNumber;
+      }
+    }
   }
 
   @override
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index c26a959..e570276 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
 description: >-
   A library to communicate with a service implementing the Dart VM
   service protocol.
-version: 2.1.0
+version: 2.1.1
 
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
diff --git a/pkg/vm_service/test/common/service_test_common.dart b/pkg/vm_service/test/common/service_test_common.dart
index b6f32cb..e5dea67 100644
--- a/pkg/vm_service/test/common/service_test_common.dart
+++ b/pkg/vm_service/test/common/service_test_common.dart
@@ -73,7 +73,8 @@
       }
     }
   });
-  await service.streamListen(EventStreams.kDebug);
+
+  await _subscribeDebugStream(service);
 
   // Pause may have happened before we subscribed.
   final isolate = await service.getIsolate(isolateRef.id);
@@ -124,22 +125,6 @@
   };
 }
 
-int _tokenToLine(Script script, int tokenPos) {
-  final table = script.tokenPosTable;
-  for (List line in table) {
-    // Each entry begins with a line number...
-    int lineNumber = line[0];
-    for (var pos = 1; pos < line.length; pos += 2) {
-      // ...and is followed by (token offset, col number) pairs.
-      int tokenOffset = line[pos];
-      if (tokenOffset == tokenPos) {
-        return lineNumber;
-      }
-    }
-  }
-  throw ArgumentError('Invalid tokenPos: $tokenPos');
-}
-
 IsolateTest stoppedAtLine(int line) {
   return (VmService service, IsolateRef isolateRef) async {
     print("Checking we are at line $line");
@@ -155,14 +140,15 @@
 
     final top = frames[0];
     final script = await service.getObject(isolate.id, top.location.script.id);
-    int actualLine = _tokenToLine(script, top.location.tokenPos);
+    int actualLine = script.getLineNumberFromTokenPos(top.location.tokenPos);
     if (actualLine != line) {
       print("Actual: $actualLine Line: $line");
       final sb = StringBuffer();
       sb.write("Expected to be at line $line but actually at line $actualLine");
       sb.write("\nFull stack trace:\n");
       for (Frame f in stack.frames) {
-        sb.write(" $f [${_tokenToLine(script, f.location.tokenPos)}]\n");
+        sb.write(
+            " $f [${script.getLineNumberFromTokenPos(f.location.tokenPos)}]\n");
       }
       throw sb.toString();
     } else {
@@ -189,17 +175,40 @@
   return completer.future;
 }
 
+Future<void> _subscribeDebugStream(VmService service) async {
+  try {
+    await service.streamListen(EventStreams.kDebug);
+  } catch (_) {
+    /* swallow exception */
+  }
+}
+
+Future<void> _unsubscribeDebugStream(VmService service) async {
+  try {
+    await service.streamCancel(EventStreams.kDebug);
+  } catch (_) {
+    /* swallow exception */
+  }
+}
+
 Future<void> stepOver(VmService service, IsolateRef isolateRef) async {
+  await service.streamListen(EventStreams.kDebug);
+  await _subscribeDebugStream(service);
   await service.resume(isolateRef.id, step: 'Over');
-  return hasStoppedAtBreakpoint(service, isolateRef);
+  await hasStoppedAtBreakpoint(service, isolateRef);
+  await _unsubscribeDebugStream(service);
 }
 
 Future<void> stepInto(VmService service, IsolateRef isolateRef) async {
+  await _subscribeDebugStream(service);
   await service.resume(isolateRef.id, step: 'Into');
-  return hasStoppedAtBreakpoint(service, isolateRef);
+  await hasStoppedAtBreakpoint(service, isolateRef);
+  await _unsubscribeDebugStream(service);
 }
 
 Future<void> stepOut(VmService service, IsolateRef isolateRef) async {
+  await _subscribeDebugStream(service);
   await service.resume(isolateRef.id, step: 'Out');
-  return hasStoppedAtBreakpoint(service, isolateRef);
+  await hasStoppedAtBreakpoint(service, isolateRef);
+  await _unsubscribeDebugStream(service);
 }
diff --git a/pkg/vm_service/test/common/test_helper.dart b/pkg/vm_service/test/common/test_helper.dart
index f57f3ee..f1725ba 100644
--- a/pkg/vm_service/test/common/test_helper.dart
+++ b/pkg/vm_service/test/common/test_helper.dart
@@ -255,7 +255,7 @@
     var process = _ServiceTesteeLauncher();
     VmService vm;
     IsolateRef isolate;
-    setUpAll(() async {
+    setUp(() async {
       await process
           .launch(pause_on_start, pause_on_exit, pause_on_unhandled_exceptions,
               testeeControlsServer, useAuthToken, extraArgs)
@@ -297,9 +297,9 @@
           testIndex++;
         }
       }
-    });
+    }, retry: 3);
 
-    tearDownAll(() {
+    tearDown(() {
       print('All service tests completed successfully.');
       process.requestExit();
     });
diff --git a/pkg/vm_service/test/debugging_test.dart b/pkg/vm_service/test/debugging_test.dart
new file mode 100644
index 0000000..8bfefd6
--- /dev/null
+++ b/pkg/vm_service/test/debugging_test.dart
@@ -0,0 +1,231 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+int counter = 0;
+
+void periodicTask(_) {
+  counter++;
+  counter++; // Line 16.  We set our breakpoint here.
+  counter++;
+  if (counter % 300 == 0) {
+    print('counter = $counter');
+  }
+}
+
+void startTimer() {
+  new Timer.periodic(const Duration(milliseconds: 10), periodicTask);
+}
+
+int getLineNumberFromTokenPos(Script s, int token) =>
+    s.tokenPosTable[token].first;
+
+var tests = <IsolateTest>[
+// Pause
+  (VmService service, IsolateRef isolateRef) async {
+    Completer completer = new Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) {
+      if (event.kind == EventKind.kPauseInterrupted) {
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+    await service.streamListen(EventStreams.kDebug);
+    await service.pause(isolateRef.id);
+    await completer.future;
+    await service.streamCancel(EventStreams.kDebug);
+  },
+
+// Resume
+  (VmService service, IsolateRef isolate) async {
+    Completer completer = Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) {
+      if (event.kind == EventKind.kResume) {
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+    await service.streamListen(EventStreams.kDebug);
+    await service.resume(isolate.id);
+    await completer.future;
+    await service.streamCancel(EventStreams.kDebug);
+  },
+
+// Add breakpoint
+  (VmService service, IsolateRef isolateRef) async {
+    Isolate isolate = await service.getIsolate(isolateRef.id);
+    final Library rootLib =
+        await service.getObject(isolate.id, isolate.rootLib.id);
+
+    // Set up a listener to wait for breakpoint events.
+    Completer completer = Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) {
+      if (event.kind == EventKind.kPauseBreakpoint) {
+        print('Breakpoint reached');
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+    await service.streamListen(EventStreams.kDebug);
+    final script =
+        await service.getObject(isolate.id, rootLib.scripts.first.id);
+    // Add the breakpoint.
+    final Breakpoint result =
+        await service.addBreakpoint(isolate.id, script.id, 16);
+    print(result);
+    expect(result is Breakpoint, isTrue);
+    Breakpoint bpt = result;
+    expect(bpt.location.script.id, script.id);
+    expect(script.getLineNumberFromTokenPos(bpt.location.tokenPos), 16);
+
+    isolate = await service.getIsolate(isolate.id);
+    expect(isolate.breakpoints.length, 1);
+
+    await completer.future; // Wait for breakpoint events.
+    await service.streamCancel(EventStreams.kDebug);
+  },
+// We are at the breakpoint on line 16.
+  (VmService service, IsolateRef isolateRef) async {
+    final stack = await service.getStack(isolateRef.id);
+    expect(stack.frames.length, greaterThanOrEqualTo(1));
+
+    Script script = await service.getObject(
+        isolateRef.id, stack.frames[0].location.script.id);
+    expect(script.uri, endsWith('debugging_test.dart'));
+    expect(script.getLineNumberFromTokenPos(stack.frames[0].location.tokenPos),
+        16);
+  },
+
+// Stepping
+  (VmService service, IsolateRef isolate) async {
+    // Set up a listener to wait for breakpoint events.
+    final completer = Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) {
+      if (event.kind == EventKind.kPauseBreakpoint) {
+        print('Breakpoint reached');
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+    print('performing step over');
+    await stepOver(service, isolate);
+    print('step over done');
+    await completer.future; // Wait for breakpoint events.
+    print('breakpoint completed');
+  },
+// We are now at line 17.
+  (VmService service, IsolateRef isolateRef) async {
+    final stack = await service.getStack(isolateRef.id);
+    expect(stack.frames.length, greaterThanOrEqualTo(1));
+
+    final Script script = await service.getObject(
+        isolateRef.id, stack.frames[0].location.script.id);
+    expect(script.uri, endsWith('debugging_test.dart'));
+    expect(script.getLineNumberFromTokenPos(stack.frames[0].location.tokenPos),
+        17);
+  },
+// Remove breakpoint
+  (VmService service, IsolateRef isolateRef) async {
+    // Set up a listener to wait for breakpoint events.
+    final completer = Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) async {
+      if (event.kind == EventKind.kBreakpointRemoved) {
+        print('Breakpoint removed');
+        final isolate = await service.getIsolate(isolateRef.id);
+        expect(isolate.breakpoints.length, 0);
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+
+    final Isolate isolate = await service.getIsolate(isolateRef.id);
+    expect(isolate.breakpoints.length, 1);
+    final bpt = isolate.breakpoints.first;
+    await service.streamListen(EventStreams.kDebug);
+    await service.removeBreakpoint(isolate.id, bpt.id);
+    await completer.future;
+    await service.streamCancel(EventStreams.kDebug);
+  },
+// Resume
+  (VmService service, IsolateRef isolate) async {
+    final completer = Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) {
+      if (event.kind == EventKind.kResume) {
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+    await resumeIsolate(service, isolate);
+    await completer.future;
+  },
+// Add breakpoint at function entry
+  (VmService service, IsolateRef isolateRef) async {
+    Isolate isolate = await service.getIsolate(isolateRef.id);
+    // Set up a listener to wait for breakpoint events.
+    final completer = Completer();
+    var stream = service.onDebugEvent;
+    var subscription;
+    subscription = stream.listen((Event event) {
+      if (event.kind == EventKind.kPauseBreakpoint) {
+        print('Breakpoint reached');
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+
+    await service.streamListen(EventStreams.kDebug);
+    final Library rootLib =
+        await service.getObject(isolate.id, isolate.rootLib.id);
+
+    // Find a specific function.
+    final FuncRef function =
+        rootLib.functions.firstWhere((f) => f.name == 'periodicTask');
+    expect(function, isNotNull);
+
+    // Add the breakpoint at function entry
+    final bpt = await service.addBreakpointAtEntry(isolate.id, function.id);
+    final Script script =
+        await service.getObject(isolate.id, bpt.location.script.id);
+    expect(script.uri, endsWith('debugging_test.dart'));
+    expect(script.getLineNumberFromTokenPos(bpt.location.tokenPos), 14);
+
+    // Refresh isolate state.
+    isolate = await service.getIsolate(isolate.id);
+    expect(isolate.breakpoints.length, 1);
+
+    await completer.future; // Wait for breakpoint events.
+  },
+// We are now at line 14.
+  (VmService service, IsolateRef isolateRef) async {
+    final stack = await service.getStack(isolateRef.id);
+    expect(stack.frames.length, greaterThanOrEqualTo(1));
+
+    final Script script = await service.getObject(
+        isolateRef.id, stack.frames[0].location.script.id);
+    expect(script.uri, endsWith('debugging_test.dart'));
+    expect(script.getLineNumberFromTokenPos(stack.frames[0].location.tokenPos),
+        14);
+  },
+];
+
+main([args = const <String>[]]) =>
+    runIsolateTests(args, tests, testeeBefore: startTimer);
diff --git a/pkg/vm_service/test/eval_test.dart b/pkg/vm_service/test/eval_test.dart
new file mode 100644
index 0000000..b751001
--- /dev/null
+++ b/pkg/vm_service/test/eval_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:developer';
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+int globalVar = 100;
+
+class MyClass {
+  static int staticVar = 1000;
+
+  static void method(int value) {
+    debugger();
+  }
+}
+
+class _MyClass {
+  void foo() {
+    debugger();
+  }
+}
+
+void testFunction() {
+  int i = 0;
+  while (true) {
+    if (++i % 100000000 == 0) {
+      MyClass.method(10000);
+      (new _MyClass()).foo();
+    }
+  }
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+
+// Evaluate against library, class, and instance.
+  (VmService service, IsolateRef isolateRef) async {
+    final isolate = await service.getIsolate(isolateRef.id);
+    final stack = await service.getStack(isolateRef.id);
+
+    // Make sure we are in the right place.
+    expect(stack.frames.length, greaterThanOrEqualTo(2));
+    expect(stack.frames[0].function.name, 'method');
+    expect(stack.frames[0].function.owner.name, 'MyClass');
+
+    final LibraryRef lib = isolate.rootLib;
+    final ClassRef cls = stack.frames[0].function.owner;
+    final InstanceRef instance = stack.frames[0].vars[0].value;
+
+    dynamic result =
+        await service.evaluate(isolate.id, lib.id, 'globalVar + 5');
+    print(result);
+    expect(result.valueAsString, '105');
+
+    await expectError(() =>
+        service.evaluate(isolate.id, lib.id, 'globalVar + staticVar + 5'));
+
+    result =
+        await service.evaluate(isolate.id, cls.id, 'globalVar + staticVar + 5');
+    print(result);
+    expect(result.valueAsString, '1105');
+
+    await expectError(() => service.evaluate(isolate.id, cls.id, 'this + 5'));
+
+    result = await service.evaluate(isolate.id, instance.id, 'this + 5');
+    print(result);
+    expect(result.valueAsString, '10005');
+
+    await expectError(
+        () => service.evaluate(isolate.id, instance.id, 'this + frog'));
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (VmService service, IsolateRef isolate) async {
+    final stack = await service.getStack(isolate.id);
+
+    // Make sure we are in the right place.
+    expect(stack.frames.length, greaterThanOrEqualTo(2));
+    expect(stack.frames[0].function.name, 'foo');
+    expect(stack.frames[0].function.owner.name, '_MyClass');
+
+    final ClassRef cls = stack.frames[0].function.owner;
+
+    final result = await service.evaluate(isolate.id, cls.id, "1+1");
+    print(result);
+    expect(result.valueAsString, "2");
+  }
+];
+
+expectError(func) async {
+  bool gotException = false;
+  dynamic result;
+  try {
+    result = await func();
+    fail('Failed to throw');
+  } on RPCError catch (e) {
+    expect(e.code, 113); // Compile time error.
+    gotException = true;
+  }
+  if (result?.type != 'Error') {
+    expect(gotException, true); // dart2 semantics
+  }
+}
+
+main([args = const <String>[]]) =>
+    runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/pkg/vm_service/test/get_allocation_profile_rpc_test.dart b/pkg/vm_service/test/get_allocation_profile_rpc_test.dart
index 4366092..0a35d093 100644
--- a/pkg/vm_service/test/get_allocation_profile_rpc_test.dart
+++ b/pkg/vm_service/test/get_allocation_profile_rpc_test.dart
@@ -64,4 +64,4 @@
   },
 ];
 
-main(args) async => runIsolateTests(args, tests);
+main([args = const <String>[]]) async => runIsolateTests(args, tests);
diff --git a/pkg/vm_service/test/get_cpu_samples_rpc_test.dart b/pkg/vm_service/test/get_cpu_samples_rpc_test.dart
index 70f640e..dcc8d9b 100644
--- a/pkg/vm_service/test/get_cpu_samples_rpc_test.dart
+++ b/pkg/vm_service/test/get_cpu_samples_rpc_test.dart
@@ -57,5 +57,5 @@
   '--profile-vm=false', // So this also works with DBC and KBC.
 ];
 
-main(args) async =>
+main([args = const <String>[]]) async =>
     runIsolateTests(args, tests, testeeBefore: testeeDo, extraArgs: vmArgs);
diff --git a/pkg/vm_service/test/get_flag_list_rpc_test.dart b/pkg/vm_service/test/get_flag_list_rpc_test.dart
index ada2cfa..f7a8b70 100644
--- a/pkg/vm_service/test/get_flag_list_rpc_test.dart
+++ b/pkg/vm_service/test/get_flag_list_rpc_test.dart
@@ -74,4 +74,4 @@
   }
 ];
 
-main(args) async => runVMTests(args, tests);
+main([args = const <String>[]]) async => runVMTests(args, tests);
diff --git a/pkg/vm_service/test/heap_snapshot_graph_test.dart b/pkg/vm_service/test/heap_snapshot_graph_test.dart
index 6fb85dd..c0db2ec 100644
--- a/pkg/vm_service/test/heap_snapshot_graph_test.dart
+++ b/pkg/vm_service/test/heap_snapshot_graph_test.dart
@@ -79,4 +79,5 @@
   },
 ];
 
-main(args) async => runIsolateTests(args, tests, testeeBefore: script);
+main([args = const <String>[]]) async =>
+    runIsolateTests(args, tests, testeeBefore: script);
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 6c01c9c..7a5fbbf 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -1333,6 +1333,10 @@
     if (name == 'Response') {
       gen.writeln('Map<String, dynamic> json;');
     }
+    if (name == 'Script') {
+      gen.writeln('final _tokenToLine = <int, int>{};');
+      gen.writeln('final _tokenToColumn = <int, int>{};');
+    }
 
     // fields
     fields.forEach((TypeField field) => field.generate(gen));
@@ -1425,6 +1429,7 @@
         }
         gen.writeln("List<List<int>>.from(json['tokenPosTable'].map"
             "((dynamic list) => List<int>.from(list)));");
+        gen.writeln('_parseTokenPosTable();');
       } else if (field.type.isArray) {
         TypeRef fieldType = field.type.types.first;
         String typesList = _typeRefListToString(field.type.types);
@@ -1471,6 +1476,10 @@
     }
     gen.writeln();
 
+    if (name == 'Script') {
+      generateScriptTypeMethods(gen);
+    }
+
     // toJson support, the base Response type is not supported
     if (name == 'Response') {
       gen.writeln('''
@@ -1555,6 +1564,39 @@
     gen.writeln('}');
   }
 
+  // Special methods for Script objects.
+  void generateScriptTypeMethods(DartGenerator gen) {
+    gen.writeDocs('''This function maps a token position to a line number.
+The VM considers the first line to be line 1.''');
+    gen.writeln(
+        'int getLineNumberFromTokenPos(int tokenPos) => _tokenToLine[tokenPos];');
+    gen.writeln();
+    gen.writeDocs('''This function maps a token position to a column number.
+The VM considers the first column to be column 1.''');
+    gen.writeln(
+        'int getColumnNumberFromTokenPos(int tokenPos) => _tokenToColumn[tokenPos];');
+    gen.writeln();
+    gen.writeln('''
+void _parseTokenPosTable() {
+  if (tokenPosTable == null) {
+    return;
+  }
+  final lineSet = Set<int>();
+  for (List line in tokenPosTable) {
+    // Each entry begins with a line number...
+    int lineNumber = line[0];
+    lineSet.add(lineNumber);
+    for (var pos = 1; pos < line.length; pos += 2) {
+      // ...and is followed by (token offset, col number) pairs.
+      final int tokenOffset = line[pos];
+      final int colNumber = line[pos + 1];
+      _tokenToLine[tokenOffset] = lineNumber;
+      _tokenToColumn[tokenOffset] = colNumber;
+    }
+  }
+}''');
+  }
+
   // Writes the code to retrieve the serialized value of a field.
   void generateSerializedFieldAccess(TypeField field, DartGenerator gen) {
     var nullAware = field.optional ? '?' : '';
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 87e6415..e22d8af 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -37,10 +37,7 @@
     extra_configs += invoker.extra_configs
   }
   source_set(target_name) {
-    configs += [
-                 "..:dart_arch_config",
-                 "..:dart_config",
-               ] + extra_configs
+    configs += [ "..:dart_config" ] + extra_configs
     public_configs = [ ":libdart_builtin_config" ]
     deps = []
     if (is_fuchsia) {
@@ -67,6 +64,7 @@
   extra_configs = [
     "..:dart_maybe_product_config",
     "..:dart_os_config",
+    "..:dart_arch_config",
   ]
 }
 
@@ -91,6 +89,14 @@
   ]
 }
 
+build_libdart_builtin("libdart_builtin_host_targeting_host") {
+  extra_configs = [ "..:dart_maybe_product_config" ]
+}
+
+build_libdart_builtin("libdart_builtin_product_host_targeting_host") {
+  extra_configs = [ "..:dart_product_config" ]
+}
+
 static_library("crashpad") {
   configs += [
     "..:dart_arch_config",
@@ -145,7 +151,6 @@
   }
   executable(target_name) {
     configs += [
-                 "..:dart_arch_config",
                  "..:dart_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
@@ -217,6 +222,7 @@
 build_gen_snapshot("gen_snapshot") {
   extra_configs = [
     "..:dart_maybe_product_config",
+    "..:dart_arch_config",
     "..:dart_os_config",
   ]
   extra_deps = [
@@ -230,6 +236,7 @@
 build_gen_snapshot("gen_snapshot_product") {
   extra_configs = [
     "..:dart_product_config",
+    "..:dart_arch_config",
     "..:dart_os_config",
   ]
   extra_deps = [
@@ -243,6 +250,7 @@
 build_gen_snapshot("gen_snapshot_fuchsia") {
   extra_configs = [
     "..:dart_maybe_product_config",
+    "..:dart_arch_config",
     "..:dart_os_fuchsia_config",
   ]
   extra_deps = [
@@ -256,6 +264,7 @@
 build_gen_snapshot("gen_snapshot_product_fuchsia") {
   extra_configs = [
     "..:dart_product_config",
+    "..:dart_arch_config",
     "..:dart_os_fuchsia_config",
   ]
   extra_deps = [
@@ -266,6 +275,26 @@
   ]
 }
 
+build_gen_snapshot("gen_snapshot_host_targeting_host") {
+  extra_configs = [ "..:dart_maybe_product_config" ]
+  extra_deps = [
+    ":gen_snapshot_dart_io_host_targeting_host",
+    ":libdart_builtin_host_targeting_host",
+    "../platform:libdart_platform_nosnapshot_with_precompiler_host_targeting_host",
+    "..:libdart_nosnapshot_with_precompiler_host_targeting_host",
+  ]
+}
+
+build_gen_snapshot("gen_snapshot_product_host_targeting_host") {
+  extra_configs = [ "..:dart_product_config" ]
+  extra_deps = [
+    ":gen_snapshot_dart_io_host_targeting_host",
+    ":libdart_builtin_host_targeting_host",
+    "../platform:libdart_platform_nosnapshot_with_precompiler_host_targeting_host",
+    "..:libdart_nosnapshot_with_precompiler_host_targeting_host",
+  ]
+}
+
 # A source set for the implementation of 'dart:io' library
 # (without secure sockets) suitable for linking with gen_snapshot.
 template("build_gen_snapshot_dart_io") {
@@ -275,7 +304,6 @@
   }
   source_set(target_name) {
     configs += [
-                 "..:dart_arch_config",
                  "..:dart_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
@@ -334,6 +362,7 @@
 build_gen_snapshot_dart_io("gen_snapshot_dart_io") {
   extra_configs = [
     "..:dart_maybe_product_config",
+    "..:dart_arch_config",
     "..:dart_os_config",
   ]
 }
@@ -341,13 +370,23 @@
 build_gen_snapshot_dart_io("gen_snapshot_dart_io_product") {
   extra_configs = [
     "..:dart_product_config",
+    "..:dart_arch_config",
     "..:dart_os_config",
   ]
 }
 
+build_gen_snapshot_dart_io("gen_snapshot_dart_io_host_targeting_host") {
+  extra_configs = [ "..:dart_maybe_product_config" ]
+}
+
+build_gen_snapshot_dart_io("gen_snapshot_dart_io_product_host_targeting_host") {
+  extra_configs = [ "..:dart_product_config" ]
+}
+
 build_gen_snapshot_dart_io("gen_snapshot_dart_io_fuchsia") {
   extra_configs = [
     "..:dart_maybe_product_config",
+    "..:dart_arch_config",
     "..:dart_os_fuchsia_config",
   ]
 }
@@ -355,6 +394,7 @@
 build_gen_snapshot_dart_io("gen_snapshot_dart_io_product_fuchsia") {
   extra_configs = [
     "..:dart_product_config",
+    "..:dart_arch_config",
     "..:dart_os_fuchsia_config",
   ]
 }
diff --git a/runtime/bin/elf_loader.h b/runtime/bin/elf_loader.h
index b604ee6..e8243cd 100644
--- a/runtime/bin/elf_loader.h
+++ b/runtime/bin/elf_loader.h
@@ -5,7 +5,7 @@
 #ifndef RUNTIME_BIN_ELF_LOADER_H_
 #define RUNTIME_BIN_ELF_LOADER_H_
 
-#include <include/dart_api.h>
+#include "../include/dart_api.h"
 
 typedef void* LoadedElfLibrary;
 
@@ -16,7 +16,7 @@
 /// string should not be 'free'-d.
 ///
 /// Looks up the Dart snapshot symbols "_kVmSnapshotData",
-/// "_kVmSnapshotInstructions", "_kVmIsoalteData" and "_kVmIsolateInstructions"
+/// "_kVmSnapshotInstructions", "_kVmIsolateData" and "_kVmIsolateInstructions"
 /// into the respectively named out-parameters.
 DART_EXPORT LoadedElfLibrary Dart_LoadELF(const char* filename,
                                           const char** error,
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 8bae36d..f4cfc6a 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -374,7 +374,7 @@
     final serviceInfo = <String, dynamic>{
       'uri': serverAddress.toString(),
     };
-    final file = File(_serviceInfoFilename);
+    final file = File.fromUri(Uri.parse(_serviceInfoFilename));
     file.writeAsString(json.encode(serviceInfo));
   }
 
diff --git a/runtime/configs.gni b/runtime/configs.gni
index a638887..843fe71 100644
--- a/runtime/configs.gni
+++ b/runtime/configs.gni
@@ -16,6 +16,8 @@
   "$_dart_runtime:dart_os_fuchsia_config",
 ]
 
+_base_host_targeting_host_config = [ "$_dart_runtime:dart_config" ]
+
 _maybe_product = [ "$_dart_runtime:dart_maybe_product_config" ]
 
 _product = [ "$_dart_runtime:dart_product_config" ]
@@ -57,6 +59,13 @@
 _nosnapshot_with_precompiler_product_fuchsia_config =
     _base_fuchsia_config + _nosnapshot_precompiler_base + _product
 
+_nosnapshot_with_precompiler_host_targeting_host_config =
+    _base_host_targeting_host_config + _nosnapshot_precompiler_base +
+    _maybe_product
+
+_nosnapshot_with_precompiler_product_host_targeting_host_config =
+    _base_host_targeting_host_config + _nosnapshot_precompiler_base + _product
+
 _all_configs = [
   {
     suffix = "_jit"
@@ -99,6 +108,16 @@
     snapshot = false
   },
   {
+    suffix = "_nosnapshot_with_precompiler_host_targeting_host"
+    configs = _nosnapshot_with_precompiler_host_targeting_host_config
+    snapshot = false
+  },
+  {
+    suffix = "_nosnapshot_with_precompiler_product_host_targeting_host"
+    configs = _nosnapshot_with_precompiler_product_host_targeting_host_config
+    snapshot = false
+  },
+  {
     suffix = "_libfuzzer"
     configs = _libfuzzer_config
     snapshot = true
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 201fe2c..947ba4f 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -287,8 +287,17 @@
 }
 
 DEFINE_NATIVE_ENTRY(OneByteString_allocate, 0, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(0));
-  return OneByteString::New(length_obj.Value(), Heap::kNew);
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, length_obj, arguments->NativeArgAt(0));
+  const int64_t length = length_obj.AsInt64Value();
+  if ((length < 0) || (length > OneByteString::kMaxElements)) {
+    // Assume that negative lengths are the result of wrapping in code in
+    // string_patch.dart.
+    const Instance& exception =
+        Instance::Handle(thread->isolate()->object_store()->out_of_memory());
+    Exceptions::Throw(thread, exception);
+    UNREACHABLE();
+  }
+  return OneByteString::New(static_cast<intptr_t>(length), Heap::kNew);
 }
 
 DEFINE_NATIVE_ENTRY(OneByteString_allocateFromOneByteList, 0, 3) {
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index af97a0f..4980516 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -9,6 +9,7 @@
 #include "vm/exceptions.h"
 #include "vm/native_entry.h"
 #include "vm/object.h"
+#include "vm/object_store.h"
 
 namespace dart {
 
@@ -189,12 +190,18 @@
 // Argument 0 is type arguments and is ignored.
 #define TYPED_DATA_NEW(name)                                                   \
   DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 0, 2) {                          \
-    GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));      \
+    GET_NON_NULL_NATIVE_ARGUMENT(Integer, length, arguments->NativeArgAt(1));  \
     const intptr_t cid = kTypedData##name##Cid;                                \
-    const intptr_t len = length.Value();                                       \
     const intptr_t max = TypedData::MaxElements(cid);                          \
-    LengthCheck(len, max);                                                     \
-    return TypedData::New(cid, len);                                           \
+    const int64_t len = length.AsInt64Value();                                 \
+    if (len < 0) {                                                             \
+      Exceptions::ThrowRangeError("length", length, 0, max);                   \
+    } else if (len > max) {                                                    \
+      const Instance& exception = Instance::Handle(                            \
+          zone, thread->isolate()->object_store()->out_of_memory());           \
+      Exceptions::Throw(thread, exception);                                    \
+    }                                                                          \
+    return TypedData::New(cid, static_cast<intptr_t>(len));                    \
   }
 
 #define TYPED_DATA_NEW_NATIVE(name) TYPED_DATA_NEW(name)
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
index 0094e6b..eca0ff7 100644
--- a/runtime/lib/wasm.cc
+++ b/runtime/lib/wasm.cc
@@ -471,9 +471,11 @@
 
 class WasmInstance {
  public:
-  WasmInstance() : _instance(nullptr), _exports(nullptr) {}
+  WasmInstance() : _instance(nullptr), _exports(nullptr), _memory(nullptr) {}
 
   bool Instantiate(wasmer_module_t* module, WasmImports* imports) {
+    ASSERT(_instance == nullptr);
+
     // Instantiate module.
     if (wasmer_module_instantiate(module, &_instance, imports->RawImports(),
                                   imports->NumImports()) !=
@@ -481,15 +483,22 @@
       return false;
     }
 
-    // Load all functions.
+    // Load all exports.
     wasmer_instance_exports(_instance, &_exports);
     intptr_t num_exports = wasmer_exports_len(_exports);
     for (intptr_t i = 0; i < num_exports; ++i) {
       wasmer_export_t* exp = wasmer_exports_get(_exports, i);
-      if (wasmer_export_kind(exp) == wasmer_import_export_kind::WASM_FUNCTION) {
+      wasmer_import_export_kind kind = wasmer_export_kind(exp);
+      if (kind == wasmer_import_export_kind::WASM_FUNCTION) {
         if (!AddFunction(exp)) {
           return false;
         }
+      } else if (kind == wasmer_import_export_kind::WASM_MEMORY) {
+        ASSERT(_memory == nullptr);
+        if (wasmer_export_to_memory(exp, &_memory) !=
+            wasmer_result_t::WASMER_OK) {
+          return false;
+        }
       }
     }
 
@@ -541,10 +550,13 @@
     o << '}' << std::endl;
   }
 
+  wasmer_memory_t* memory() { return _memory; }
+
  private:
   wasmer_instance_t* _instance;
   wasmer_exports_t* _exports;
   MallocDirectChainedHashMap<CStringKeyValueTrait<WasmFunction*>> _functions;
+  wasmer_memory_t* _memory;
 
   static classid_t ToDartType(wasmer_value_tag wasm_type) {
     switch (wasm_type) {
@@ -840,6 +852,36 @@
   return Object::null();
 }
 
+DEFINE_NATIVE_ENTRY(Wasm_initMemoryFromInstance, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(1));
+
+  ASSERT(mem_wrap.NumNativeFields() == 1);
+  ASSERT(inst_wrap.NumNativeFields() == 1);
+
+  WasmInstance* inst =
+      reinterpret_cast<WasmInstance*>(inst_wrap.GetNativeField(0));
+
+  wasmer_memory_t* memory = inst->memory();
+
+  mem_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(memory));
+  FinalizablePersistentHandle::New(thread->isolate(), mem_wrap, memory,
+                                   FinalizeWasmMemory,
+                                   wasmer_memory_length(memory));
+  return WasmMemoryToExternalTypedData(memory);
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_getMemoryPages, 0, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
+
+  ASSERT(mem_wrap.NumNativeFields() == 1);
+
+  wasmer_memory_t* memory =
+      reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
+
+  return Integer::New(wasmer_memory_length(memory));
+}
+
 DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, fn_wrap, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(1));
@@ -978,6 +1020,16 @@
   return nullptr;
 }
 
+DEFINE_NATIVE_ENTRY(Wasm_initMemoryFromInstance, 0, 2) {
+  Exceptions::ThrowUnsupportedError("WASM is disabled");
+  return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_getMemoryPages, 0, 1) {
+  Exceptions::ThrowUnsupportedError("WASM is disabled");
+  return nullptr;
+}
+
 DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
   Exceptions::ThrowUnsupportedError("WASM is disabled");
   return nullptr;
diff --git a/runtime/observatory/tests/service/auth_token1_test.dart b/runtime/observatory/tests/service/auth_token1_test.dart
deleted file mode 100644
index 4d4fa9a..0000000
--- a/runtime/observatory/tests/service/auth_token1_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:developer';
-import 'dart:io' as io;
-import 'package:observatory/service_io.dart' as S;
-import 'package:unittest/unittest.dart';
-import 'test_helper.dart';
-
-Future<Null> testeeBefore() async {
-  print('testee before');
-  print(await Service.getInfo());
-  // Start the web server.
-  ServiceProtocolInfo info = await Service.controlWebServer(enable: true);
-  expect(info.serverUri, isNotNull);
-  // Ensure that we have no auth token in the path segments.
-  expect(info.serverUri.pathSegments.length, equals(0));
-
-  // Try connecting to the server without the auth token, it should succeed.
-  var port = info.serverUri.port;
-  var url = Uri.parse('http://localhost:$port');
-  var httpClient = new io.HttpClient();
-  try {
-    await httpClient.getUrl(url);
-    expect(true, true);
-  } catch (e) {
-    expect(true, false);
-  }
-}
-
-var tests = <IsolateTest>[
-  (S.Isolate isolate) async {
-    await isolate.reload();
-    // Just getting here means that the testee enabled the service protocol
-    // web server.
-    expect(true, true);
-  }
-];
-
-main(args) => runIsolateTests(args, tests,
-    testeeBefore: testeeBefore,
-    // the testee is responsible for starting the
-    // web server.
-    testeeControlsServer: true,
-    useAuthToken: false);
diff --git a/runtime/observatory/tests/service/auth_token_test.dart b/runtime/observatory/tests/service/auth_token_test.dart
index 470b330..8c6ae7f 100644
--- a/runtime/observatory/tests/service/auth_token_test.dart
+++ b/runtime/observatory/tests/service/auth_token_test.dart
@@ -54,5 +54,4 @@
     testeeBefore: testeeBefore,
     // the testee is responsible for starting the
     // web server.
-    testeeControlsServer: true,
-    useAuthToken: true);
+    testeeControlsServer: true);
diff --git a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
index 637790f..3884a9b 100644
--- a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
@@ -119,7 +119,7 @@
     expect(result['traceEvents'], new isInstanceOf<List>());
     final int numEvents = result['traceEvents'].length;
     List dartEvents = filterForDartEvents(result['traceEvents']);
-    expect(dartEvents.length, equals(11));
+    expect(dartEvents.length, greaterThanOrEqualTo(11));
     allEventsHaveIsolateNumber(dartEvents);
     allEventsHaveIsolateNumber(result['traceEvents']);
     expect(
diff --git a/runtime/observatory/tests/service/http_auth_get_isolate_rpc_test.dart b/runtime/observatory/tests/service/http_auth_get_isolate_rpc_test.dart
index 5b0b5f6..261fa26 100644
--- a/runtime/observatory/tests/service/http_auth_get_isolate_rpc_test.dart
+++ b/runtime/observatory/tests/service/http_auth_get_isolate_rpc_test.dart
@@ -10,6 +10,5 @@
       testeeBefore: testeeBefore,
       // the testee is responsible for starting the
       // web server.
-      testeeControlsServer: true,
-      useAuthToken: true);
+      testeeControlsServer: true);
 }
diff --git a/runtime/observatory/tests/service/http_auth_get_vm_rpc_test.dart b/runtime/observatory/tests/service/http_auth_get_vm_rpc_test.dart
index 8eff61f..5484c5e 100644
--- a/runtime/observatory/tests/service/http_auth_get_vm_rpc_test.dart
+++ b/runtime/observatory/tests/service/http_auth_get_vm_rpc_test.dart
@@ -10,6 +10,5 @@
       testeeBefore: testeeBefore,
       // the testee is responsible for starting the
       // web server.
-      testeeControlsServer: true,
-      useAuthToken: true);
+      testeeControlsServer: true);
 }
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions3_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions3_test.dart
new file mode 100644
index 0000000..454c1c2
--- /dev/null
+++ b/runtime/observatory/tests/service/pause_on_unhandled_async_exceptions3_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that debugger can stop on an unhandled exception thrown from async
+// function. Regression test for https://dartbug.com/38697.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+const LINE_A = 16;
+
+throwException() async {
+  throw 'exception'; // LINE_A
+}
+
+testeeMain() async {
+  try {
+    await throwException();
+  } finally {}
+}
+
+var tests = <IsolateTest>[
+  hasStoppedWithUnhandledException,
+  stoppedAtLine(LINE_A),
+  (Isolate isolate) async {
+    print("Stopped!");
+    var stack = await isolate.getStack();
+    expect(stack['frames'][0].function.toString(), contains('throwException'));
+  }
+];
+
+main(args) => runIsolateTests(args, tests,
+    pause_on_unhandled_exceptions: true, testeeConcurrent: testeeMain);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 05c37a1..10ae2e3 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -92,13 +92,12 @@
       bool pause_on_exit,
       bool pause_on_unhandled_exceptions,
       bool testeeControlsServer,
-      bool useAuthToken,
+      Uri serviceInfoUri,
       List<String> extraArgs) {
     assert(pause_on_start != null);
     assert(pause_on_exit != null);
     assert(pause_on_unhandled_exceptions != null);
     assert(testeeControlsServer != null);
-    assert(useAuthToken != null);
 
     if (_shouldLaunchSkyShell()) {
       return _spawnSkyProcess(pause_on_start, pause_on_exit,
@@ -109,7 +108,7 @@
           pause_on_exit,
           pause_on_unhandled_exceptions,
           testeeControlsServer,
-          useAuthToken,
+          serviceInfoUri,
           extraArgs);
     }
   }
@@ -119,7 +118,7 @@
       bool pause_on_exit,
       bool pause_on_unhandled_exceptions,
       bool testeeControlsServer,
-      bool useAuthToken,
+      Uri serviceInfoUri,
       List<String> extraArgs) {
     assert(!_shouldLaunchSkyShell());
 
@@ -132,9 +131,8 @@
     if (pause_on_exit) {
       fullArgs.add('--pause-isolates-on-exit');
     }
-    if (!useAuthToken) {
-      fullArgs.add('--disable-service-auth-codes');
-    }
+    fullArgs.add('--write-service-info=$serviceInfoUri');
+
     if (pause_on_unhandled_exceptions) {
       fullArgs.add('--pause-isolates-on-unhandled-exceptions');
     }
@@ -149,8 +147,7 @@
     }
     fullArgs.addAll(args);
 
-    return _spawnCommon(dartExecutable, fullArgs,
-        <String, String>{});
+    return _spawnCommon(dartExecutable, fullArgs, <String, String>{});
   }
 
   Future<Process> _spawnSkyProcess(
@@ -211,37 +208,27 @@
       bool pause_on_exit,
       bool pause_on_unhandled_exceptions,
       bool testeeControlsServer,
-      bool useAuthToken,
-      List<String> extraArgs) {
-    return _spawnProcess(
-        pause_on_start,
-        pause_on_exit,
-        pause_on_unhandled_exceptions,
-        testeeControlsServer,
-        useAuthToken,
-        extraArgs).then((p) {
-      Completer<Uri> completer = new Completer<Uri>();
+      List<String> extraArgs) async {
+    final completer = new Completer<Uri>();
+    final serviceInfoDir =
+        await Directory.systemTemp.createTemp('dart_service');
+    final serviceInfoUri = serviceInfoDir.uri.resolve('service_info.json');
+    final serviceInfoFile = await File.fromUri(serviceInfoUri).create();
+    _spawnProcess(pause_on_start, pause_on_exit, pause_on_unhandled_exceptions,
+            testeeControlsServer, serviceInfoUri, extraArgs)
+        .then((p) async {
       process = p;
       Uri uri;
-      var blank;
-      var first = true;
+      final blankCompleter = Completer();
+      bool blankLineReceived = false;
       process.stdout
           .transform(utf8.decoder)
           .transform(new LineSplitter())
           .listen((line) {
-        const kObservatoryListening = 'Observatory listening on ';
-        if (line.startsWith(kObservatoryListening)) {
-          uri = Uri.parse(line.substring(kObservatoryListening.length));
-        }
-        if (pause_on_start || line == '') {
+        if (!blankLineReceived && (pause_on_start || line == '')) {
           // Received blank line.
-          blank = true;
-        }
-        if ((uri != null) && (blank == true) && (first == true)) {
-          completer.complete(uri);
-          // Stop repeat completions.
-          first = false;
-          print('** Signaled to run test queries on $uri');
+          blankLineReceived = true;
+          blankCompleter.complete();
         }
         print('>testee>out> $line');
       });
@@ -257,8 +244,20 @@
         }
         print("** Process exited");
       });
-      return completer.future;
+
+      // Wait for the blank line which signals that we're ready to run.
+      await blankCompleter.future;
+      while ((await serviceInfoFile.length()) <= 5) {
+        await Future.delayed(Duration(milliseconds: 50));
+      }
+      final content = await serviceInfoFile.readAsString();
+      final infoJson = json.decode(content);
+      uri = Uri.parse(infoJson['uri']);
+      completer.complete(uri);
+      print('** Signaled to run test queries on $uri');
+      await serviceInfoDir.delete(recursive: true);
     });
+    return completer.future;
   }
 
   void requestExit() {
@@ -287,14 +286,13 @@
       bool pause_on_exit: false,
       bool verbose_vm: false,
       bool pause_on_unhandled_exceptions: false,
-      bool testeeControlsServer: false,
-      bool useAuthToken: false}) {
+      bool testeeControlsServer: false}) {
     var process = new _ServiceTesteeLauncher();
     bool testsDone = false;
     runZoned(() {
       process
           .launch(pause_on_start, pause_on_exit, pause_on_unhandled_exceptions,
-              testeeControlsServer, useAuthToken, extraArgs)
+              testeeControlsServer, extraArgs)
           .then((Uri serverAddress) async {
         if (mainArgs.contains("--gdb")) {
           var pid = process.process.pid;
@@ -406,7 +404,6 @@
     bool verbose_vm: false,
     bool pause_on_unhandled_exceptions: false,
     bool testeeControlsServer: false,
-    bool useAuthToken: false,
     List<String> extraArgs}) async {
   assert(!pause_on_start || testeeBefore == null);
   if (_isTestee()) {
@@ -424,8 +421,7 @@
         pause_on_exit: pause_on_exit,
         verbose_vm: verbose_vm,
         pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
-        testeeControlsServer: testeeControlsServer,
-        useAuthToken: useAuthToken);
+        testeeControlsServer: testeeControlsServer);
   }
 }
 
diff --git a/runtime/platform/safe_stack.h b/runtime/platform/safe_stack.h
index 3c68059..5a9bbeb 100644
--- a/runtime/platform/safe_stack.h
+++ b/runtime/platform/safe_stack.h
@@ -19,4 +19,16 @@
 #define NO_SANITIZE_SAFE_STACK
 #endif
 
+#if defined(__has_feature)
+#if __has_feature(shadow_call_stack)
+#define USING_SHADOW_CALL_STACK
+#endif
+#endif
+
+#if defined(USING_SHADOW_CALL_STACK)
+#define NO_SANITIZE_SHADOW_CALL_STACK __attribute__((no_sanitize("shadow-call-stack")))
+#else
+#define NO_SANITIZE_SHADOW_CALL_STACK
+#endif
+
 #endif  // RUNTIME_PLATFORM_SAFE_STACK_H_
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index 2cfa649..3f5091c 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -50,6 +50,26 @@
   return r;
 }
 
+uint64_t Utils::ReverseBits64(uint64_t x) {
+  const uint64_t one = static_cast<uint64_t>(1);
+  uint64_t result = 0;
+  for (uint64_t rbit = one << 63; x != 0; x >>= 1) {
+    if ((x & one) != 0) result |= rbit;
+    rbit >>= 1;
+  }
+  return result;
+}
+
+uint32_t Utils::ReverseBits32(uint32_t x) {
+  const uint32_t one = static_cast<uint32_t>(1);
+  uint32_t result = 0;
+  for (uint32_t rbit = one << 31; x != 0; x >>= 1) {
+    if ((x & one) != 0) result |= rbit;
+    rbit >>= 1;
+  }
+  return result;
+}
+
 // Implementation according to H.S.Warren's "Hacker's Delight"
 // (Addison Wesley, 2002) Chapter 10 and T.Grablund, P.L.Montogomery's
 // "Division by Invariant Integers Using Multiplication" (PLDI 1994).
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index e0d145b..860c00b 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -150,6 +150,17 @@
   static int CountLeadingZeros(uword x);
   static int CountTrailingZeros(uword x);
 
+  static uint64_t ReverseBits64(uint64_t x);
+  static uint32_t ReverseBits32(uint32_t x);
+
+  static uword ReverseBitsWord(uword x) {
+#ifdef ARCH_IS_64_BIT
+    return ReverseBits64(x);
+#else
+    return ReverseBits32(x);
+#endif
+  }
+
   // Computes magic numbers to implement DIV or MOD operator.
   static void CalculateMagicAndShiftForDivRem(int64_t divisor,
                                               int64_t* magic,
diff --git a/runtime/tests/vm/dart/regress_38661_test.dart b/runtime/tests/vm/dart/regress_38661_test.dart
new file mode 100644
index 0000000..2e1ba13
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_38661_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
+// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
+// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
+// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
+// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
+
+class A {
+  const A();
+}
+
+class B {
+  Object a = const A();
+}
+
+foo(int i) {
+  if (i == 3) {
+    new B();
+  }
+}
+
+main(args) {
+  foo(4);
+}
diff --git a/runtime/tools/layering_check.py b/runtime/tools/compiler_layering_check.py
similarity index 100%
rename from runtime/tools/layering_check.py
rename to runtime/tools/compiler_layering_check.py
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index 162c2e0..94989a2 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -20,6 +20,7 @@
     --seed      : defines random seed (system-set by default)
     --[no-]fp   : enables/disables floating-point operations (default: on)
     --[no-]ffi  : enables/disables FFI method calls (default: off)
+    --[no-]flat : enables/disables flat types (default: off)
     --[no-]mini : enables minimization mode (default: off)
     --smask     : bitmask indicating which statements to omit (Bit=1 omits, defaults to "0")
     --emask     : bitmask indicating which expressions to omit (Bit=1 omits, defaults to "0")
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 21f0a79..d09a711 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -7,14 +7,14 @@
 
 import 'package:args/args.dart';
 
-import 'dartfuzz_values.dart';
 import 'dartfuzz_api_table.dart';
 import 'dartfuzz_ffi_api.dart';
+import 'dartfuzz_type_table.dart';
 
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.53';
+const String version = '1.57';
 
 // Restriction on statements and expressions.
 const int stmtDepth = 1;
@@ -39,10 +39,7 @@
 class RhsFilter {
   RhsFilter(this._remaining, this.lhsVar);
   factory RhsFilter.fromDartType(DartType tp, String lhsVar) {
-    if (tp == DartType.STRING ||
-        tp == DartType.INT_LIST ||
-        tp == DartType.INT_SET ||
-        tp == DartType.INT_STRING_MAP) {
+    if (DartType.isGrowableType(tp)) {
       return RhsFilter(1, lhsVar);
     }
     return null;
@@ -114,7 +111,7 @@
 
 /// Class that generates a random, but runnable Dart program for fuzz testing.
 class DartFuzz {
-  DartFuzz(this.seed, this.fp, this.ffi, this.file,
+  DartFuzz(this.seed, this.fp, this.ffi, this.flatTp, this.file,
       {this.minimize = false, this.smask, this.emask});
 
   void run() {
@@ -124,6 +121,8 @@
     nest = 0;
     currentClass = null;
     currentMethod = null;
+    // Setup Dart types.
+    dartType = DartType.fromDartConfig(enableFp: fp, disableNesting: flatTp);
     // Setup minimization parameters.
     initMinimization();
     // Setup the library and ffi api.
@@ -131,16 +130,14 @@
     // Setup the types.
     localVars = <DartType>[];
     iterVars = <String>[];
-
     globalVars = fillTypes1(limit: numGlobalVars);
-    globalVars.addAll(DartType.allTypes); // always one each
+    globalVars.addAll(dartType.allTypes);
     globalMethods =
         fillTypes2(limit2: numGlobalMethods, limit1: numMethodParams);
     classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
     final int numClassMethods = 1 + numClasses - classFields.length;
     classMethods = fillTypes3(classFields.length,
         limit2: numClassMethods, limit1: numMethodParams);
-
     virtualClassMethods = <Map<int, List<int>>>[];
     classParents = <int>[];
     // Setup optional ffi methods and types.
@@ -167,6 +164,13 @@
     assert(localVars.isEmpty);
   }
 
+  // Randomly specialize interface if possible. E.g. num to int.
+  DartType maybeSpecializeInterface(DartType tp) {
+    if (!dartType.isSpecializable(tp)) return tp;
+    DartType resolvedTp = oneOfSet(dartType.interfaces(tp));
+    return resolvedTp;
+  }
+
   //
   // Minimization components.
   //
@@ -192,13 +196,13 @@
       case DartType.STRING:
         emit('"a"');
         break;
-      case DartType.INT_LIST:
+      case DartType.LIST_INT:
         emit('[1]');
         break;
-      case DartType.INT_SET:
+      case DartType.SET_INT:
         emit('{1}');
         break;
-      case DartType.INT_STRING_MAP:
+      case DartType.MAP_INT_STRING:
         emit('{1: "a"}');
         break;
       default:
@@ -304,7 +308,7 @@
     emitLn('// The Dart Project Fuzz Tester ($version).');
     emitLn('// Program generated as:');
     emitLn('//   dart dartfuzz.dart --seed $seed --${fp ? "" : "no-"}fp ' +
-        '--${ffi ? "" : "no-"}ffi');
+        '--${ffi ? "" : "no-"}ffi --${flatTp ? "" : "no-"}flat');
     emitLn('');
     emitLn("import 'dart:async';");
     emitLn("import 'dart:cli';");
@@ -567,7 +571,7 @@
     for (int i = 0; i < vars.length; i++) {
       DartType tp = vars[i];
       emitLn('${tp.name} $name$i = ', newline: false);
-      emitLiteral(0, tp);
+      emitConstructorOrLiteral(0, tp);
       emit(';', newline: true);
     }
     emit('', newline: true);
@@ -616,22 +620,42 @@
 
   // Emit an assignment statement.
   bool emitAssign() {
-    DartType tp = getType();
+    // Select a type at random.
+    final tp = oneOfSet(dartType.allTypes);
+    // Select one of the assign operations for the given type.
+    final assignOp = oneOfSet(dartType.assignOps(tp));
+    if (assignOp == null) {
+      throw 'No assign operation for ${tp.name}';
+    }
     emitLn('', newline: false);
+    // Emit a variable of the lhs type.
     final emittedVar = emitVar(0, tp, isLhs: true);
     RhsFilter rhsFilter = RhsFilter.fromDartType(tp, emittedVar);
-    final assignOp = emitAssignOp(tp);
     if ({'*=', '+='}.contains(assignOp)) {
       rhsFilter?.consume();
     }
-    emitExpr(0, tp, rhsFilter: rhsFilter);
+    emit(" $assignOp ");
+    // Select one of the possible rhs types for the given lhs type and assign
+    // operation.
+    DartType rhsType = oneOfSet(dartType.assignOpRhs(tp, assignOp));
+    if (rhsType == null) {
+      throw 'No rhs type for assign ${tp.name} $assignOp';
+    }
+
+    // We need to avoid cases of "abcde" *= large number in loops.
+    if (assignOp == "*=" && tp == DartType.STRING && rhsType == DartType.INT) {
+      emitSmallPositiveInt();
+    } else {
+      // Emit an expression for the right hand side.
+      emitExpr(0, rhsType, rhsFilter: rhsFilter);
+    }
     emit(';', newline: true);
     return true;
   }
 
   // Emit a print statement.
   bool emitPrint() {
-    DartType tp = getType();
+    DartType tp = oneOfSet(dartType.allTypes);
     emitLn('print(', newline: false);
     emitExpr(0, tp);
     emit(');', newline: true);
@@ -653,7 +677,7 @@
 
   // Emit a throw statement.
   bool emitThrow() {
-    DartType tp = getType();
+    DartType tp = oneOfSet(dartType.allTypes);
     emitLn('throw ', newline: false);
     emitExpr(0, tp);
     emit(';', newline: true);
@@ -710,14 +734,21 @@
   // Emit a simple membership for-in-loop.
   bool emitForIn(int depth) {
     final int i = localVars.length;
-    emitLn('for (int $localName$i in ', newline: false);
+    // Select one iterable type to be used in 'for in' statement.
+    final iterType = oneOfSet(dartType.iterableTypes1);
+    // Get the element type contained within the iterable type.
+    final elementType = dartType.elementType(iterType);
+    if (elementType == null) {
+      throw 'No element type for iteration type ${iterType.name}';
+    }
+    emitLn('for (${elementType.name} $localName$i in ', newline: false);
     localVars.add(null); // declared, but don't use
-    emitExpr(0, rand.nextBool() ? DartType.INT_LIST : DartType.INT_SET);
+    emitExpr(0, iterType);
     localVars.removeLast(); // will get type
     emit(') {', newline: true);
     indent += 2;
     nest++;
-    localVars.add(DartType.INT);
+    localVars.add(elementType);
     emitStatements(depth + 1);
     localVars.removeLast();
     nest--;
@@ -731,15 +762,19 @@
     final int i = localVars.length;
     final int j = i + 1;
     emitLn("", newline: false);
-    final emittedVar = emitScalarVar(DartType.INT_STRING_MAP, isLhs: false);
+    // Select one map type to be used in forEach loop.
+    final mapType = oneOfSet(dartType.mapTypes);
+    final emittedVar = emitScalarVar(mapType, isLhs: false);
     iterVars.add(emittedVar);
     emit('.forEach(($localName$i, $localName$j) {\n');
     indent += 2;
     final int nestTmp = nest;
     // Reset, since forEach cannot break out of own or enclosing context.
     nest = 0;
-    localVars.add(DartType.INT);
-    localVars.add(DartType.STRING);
+    // Get the type of the map key and add it to the local variables.
+    localVars.add(dartType.indexType(mapType));
+    // Get the type of the map values and add it to the local variables.
+    localVars.add(dartType.elementType(mapType));
     emitStatements(depth + 1);
     localVars.removeLast();
     localVars.removeLast();
@@ -837,7 +872,7 @@
 
   // Emit a new program scope that introduces a new local variable.
   bool emitScope(int depth) {
-    DartType tp = getType();
+    DartType tp = oneOfSet(dartType.allTypes);
     final int i = localVars.length;
     emitLn('{ ${tp.name} $localName$i = ', newline: false);
     localVars.add(null); // declared, but don't use
@@ -970,7 +1005,7 @@
         emitSmallNegativeInt();
         break;
       default:
-        emit('${oneOf(DartFuzzValues.interestingIntegers)}');
+        emit('${oneOf(interestingIntegers)}');
         break;
     }
   }
@@ -979,15 +1014,26 @@
     emit('${rand.nextDouble()}');
   }
 
+  void emitNum({bool smallPositiveValue = false}) {
+    if (!fp || rand.nextInt(2) == 0) {
+      if (smallPositiveValue) {
+        emitSmallPositiveInt();
+      } else {
+        emitInt();
+      }
+    } else {
+      emitDouble();
+    }
+  }
+
   void emitChar() {
     switch (rand.nextInt(10)) {
       // Favors regular char.
       case 0:
-        emit(oneOf(DartFuzzValues.interestingChars));
+        emit(oneOf(interestingChars));
         break;
       default:
-        emit(DartFuzzValues
-            .regularChars[rand.nextInt(DartFuzzValues.regularChars.length)]);
+        emit(regularChars[rand.nextInt(regularChars.length)]);
         break;
     }
   }
@@ -1001,6 +1047,8 @@
   }
 
   void emitElementExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
+    // This check determines whether we are emitting a global variable.
+    // I.e. whenever we are not currently emitting part of a class.
     if (currentMethod != null) {
       emitExpr(depth, tp, rhsFilter: rhsFilter);
     } else {
@@ -1009,18 +1057,39 @@
   }
 
   void emitElement(int depth, DartType tp, {RhsFilter rhsFilter}) {
-    if (tp == DartType.INT_STRING_MAP) {
-      emitSmallPositiveInt();
+    // Get the element type contained in type tp.
+    // E.g. element type of List<String> is String.
+    final elementType = dartType.elementType(tp);
+    // Decide whether we need to generate Map or List/Set type elements.
+    if (DartType.isMapType(tp)) {
+      // Emit construct for the map key type.
+      final indexType = dartType.indexType(tp);
+      // This check determines whether we are emitting a global variable.
+      // I.e. whenever we are not currently emitting part of a class.
+      if (currentMethod != null) {
+        emitExpr(depth, indexType, rhsFilter: rhsFilter);
+      } else {
+        emitLiteral(depth, indexType, rhsFilter: rhsFilter);
+      }
       emit(' : ');
-      emitElementExpr(depth, DartType.STRING, rhsFilter: rhsFilter);
+      // Emit construct for the map value type.
+      emitElementExpr(depth, elementType, rhsFilter: rhsFilter);
     } else {
-      emitElementExpr(depth, DartType.INT, rhsFilter: rhsFilter);
+      // List and Set types.
+      emitElementExpr(depth, elementType, rhsFilter: rhsFilter);
     }
   }
 
   void emitCollectionElement(int depth, DartType tp, {RhsFilter rhsFilter}) {
     int r = depth <= exprDepth ? rand.nextInt(10) : 10;
-    switch (r + 3) {
+    // TODO (felih): disable complex collection constructs for new types for
+    // now.
+    if (!{DartType.MAP_INT_STRING, DartType.LIST_INT, DartType.SET_INT}
+        .contains(tp)) {
+      emitElement(depth, tp, rhsFilter: rhsFilter);
+      return;
+    }
+    switch (r) {
       // Favors elements over control-flow collections.
       case 0:
         // TODO (ajcbik): Remove restriction once compiler is fixed.
@@ -1044,6 +1113,8 @@
       case 2:
         {
           final int i = localVars.length;
+          // TODO (felih): update to use new type system. Add types like
+          // LIST_STRING etc.
           emit('for (int $localName$i ');
           // For-loop (induction, list, set).
           localVars.add(null); // declared, but don't use
@@ -1055,13 +1126,13 @@
               break;
             case 1:
               emit('in ');
-              emitCollection(depth + 1, DartType.INT_LIST,
+              emitCollection(depth + 1, DartType.LIST_INT,
                   rhsFilter: rhsFilter);
               emit(') ');
               break;
             default:
               emit('in ');
-              emitCollection(depth + 1, DartType.INT_SET, rhsFilter: rhsFilter);
+              emitCollection(depth + 1, DartType.SET_INT, rhsFilter: rhsFilter);
               emit(') ');
               break;
           }
@@ -1082,18 +1153,22 @@
   }
 
   void emitCollection(int depth, DartType tp, {RhsFilter rhsFilter}) {
-    emit(tp == DartType.INT_LIST ? '[ ' : '{ ');
-    for (int i = 0, n = 1 + rand.nextInt(8); i < n; i++) {
+    // Collection length decreases as depth increases.
+    int collectionLength = max(1, 8 - depth);
+    emit(DartType.isListType(tp) ? '[ ' : '{ ');
+    for (int i = 0, n = 1 + rand.nextInt(collectionLength); i < n; i++) {
       emitCollectionElement(depth, tp, rhsFilter: rhsFilter);
       if (i != (n - 1)) {
         emit(', ');
       }
     }
-    emit(tp == DartType.INT_LIST ? ' ]' : ' }');
+    emit(DartType.isListType(tp) ? ' ]' : ' }');
   }
 
   void emitLiteral(int depth, DartType tp,
       {bool smallPositiveValue = false, RhsFilter rhsFilter}) {
+    // Randomly specialize interface if possible. E.g. num to int.
+    tp = maybeSpecializeInterface(tp);
     if (tp == DartType.BOOL) {
       emitBool();
     } else if (tp == DartType.INT) {
@@ -1104,20 +1179,70 @@
       }
     } else if (tp == DartType.DOUBLE) {
       emitDouble();
+    } else if (tp == DartType.NUM) {
+      emitNum(smallPositiveValue: smallPositiveValue);
     } else if (tp == DartType.STRING) {
       emitString();
-    } else if (tp == DartType.INT_LIST ||
-        tp == DartType.INT_SET ||
-        tp == DartType.INT_STRING_MAP) {
+    } else if (dartType.constructors(tp).isNotEmpty) {
+      // Constructors serve as literals for non trivially constructable types.
+      // Important note: We have to test for existence of a non trivial
+      // constructor before testing for list type assiciation, since some types
+      // like ListInt32 are of list type but can not be constructed
+      // from a literal.
+      emitConstructorOrLiteral(depth + 1, tp, rhsFilter: rhsFilter);
+    } else if (DartType.isCollectionType(tp)) {
       final resetExprStmt = processExprOpen(tp);
-      emitCollection(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
+      emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
       processExprClose(resetExprStmt);
     } else {
-      assert(false);
+      throw 'Can not emit literal for type ${tp.name}';
+    }
+  }
+
+  // Emit a constructor for a type, this can either be a trivial constructor
+  // (i.e. parsed from a literal) or an actual function invocation.
+  void emitConstructorOrLiteral(int depth, DartType tp, {RhsFilter rhsFilter}) {
+    // If there is at least one non trivial constructor for the type tp
+    // select one of these constructors.
+    if (dartType.hasConstructor(tp)) {
+      String constructor = oneOfSet(dartType.constructors(tp));
+      // There are two types of constructors, named constructors and 'empty'
+      // constructors (e.g. X.fromList(...) and new X(...) respectively).
+      // Empty constructors are invoked with new + type name, non-empty
+      // constructors are static functions of the type.
+      if (!constructor.isEmpty) {
+        emit('${tp.name}');
+        emit('.${constructor}');
+      } else {
+        emit('new ${tp.name}');
+      }
+      emit('(');
+      // Iterate over constructor parameters.
+      List<DartType> constructorParameters =
+          dartType.constructorParameters(tp, constructor);
+      if (constructorParameters == null) {
+        throw 'No constructor parameters for ${tp.name}.$constructor';
+      }
+      for (int i = 0, n = constructorParameters.length; i < n; ++i) {
+        // If we are emitting a constructor parameter, we want to use small
+        // values to avoid programs that run out of memory.
+        // TODO (felih): maybe allow occasionally?
+        emitLiteral(depth + 1, constructorParameters[i],
+            smallPositiveValue: true, rhsFilter: rhsFilter);
+        if (i != n - 1) {
+          emit(", ");
+        }
+      }
+      emit(')');
+    } else {
+      // Otherwise type can be constructed from a literal.
+      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
     }
   }
 
   String emitScalarVar(DartType tp, {bool isLhs = false, RhsFilter rhsFilter}) {
+    // Randomly specialize interface type, unless emitting left hand side.
+    if (!isLhs) tp = maybeSpecializeInterface(tp);
     // Collect all choices from globals, fields, locals, and parameters.
     Set<String> choices = <String>{};
     for (int i = 0; i < globalVars.length; i++) {
@@ -1156,7 +1281,7 @@
       if (cleanChoices.isNotEmpty) {
         choices = cleanChoices;
       } else if (!isLhs) {
-        // If we are emitting an RHS variable, we can emit a terminal.
+        // If we are emitting an rhs variable, we can emit a terminal.
         // note that if the variable type is a collection, this might
         // still result in a recursion.
         emitLiteral(0, tp);
@@ -1179,17 +1304,17 @@
   String emitSubscriptedVar(int depth, DartType tp,
       {bool isLhs = false, RhsFilter rhsFilter}) {
     String ret;
-    if (tp == DartType.INT) {
-      ret =
-          emitScalarVar(DartType.INT_LIST, isLhs: isLhs, rhsFilter: rhsFilter);
+    // Check if type tp is an indexable element of some other type.
+    if (dartType.isIndexableElementType(tp)) {
+      // Select a list or map type that contains elements of type tp.
+      final iterType = oneOfSet(dartType.indexableElementTypes(tp));
+      // Get the index type for the respective list or map type.
+      final indexType = dartType.indexType(iterType);
+      // Emit a variable of the selected list or map type.
+      ret = emitScalarVar(iterType, isLhs: isLhs, rhsFilter: rhsFilter);
       emit('[');
-      emitExpr(depth + 1, DartType.INT);
-      emit(']');
-    } else if (tp == DartType.STRING) {
-      ret = emitScalarVar(DartType.INT_STRING_MAP,
-          isLhs: isLhs, rhsFilter: rhsFilter);
-      emit('[');
-      emitExpr(depth + 1, DartType.INT);
+      // Emit an expression resolving into the index type.
+      emitExpr(depth + 1, indexType);
       emit(']');
     } else {
       ret = emitScalarVar(tp,
@@ -1235,36 +1360,55 @@
 
   // Emit expression with unary operator: (~(x))
   void emitUnaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
-    if (tp == DartType.BOOL || tp == DartType.INT || tp == DartType.DOUBLE) {
-      emit('(');
-      emitUnaryOp(tp);
-      emit('(');
-      emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
-      emit('))');
-    } else {
-      emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal
+    if (dartType.uniOps(tp).isEmpty) {
+      return emitTerminal(depth, tp, rhsFilter: rhsFilter);
     }
+    emit('(');
+    emit(oneOfSet(dartType.uniOps(tp)));
+    emit('(');
+    emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
+    emit('))');
   }
 
   // Emit expression with binary operator: (x + y)
   void emitBinaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
-    if (tp == DartType.BOOL) {
-      // For boolean, allow type switch with relational op.
-      if (rand.nextInt(2) == 0) {
-        DartType deeper_tp = getType();
-        emit('(');
-        emitExpr(depth + 1, deeper_tp, rhsFilter: rhsFilter);
-        emitRelOp(deeper_tp);
-        emitExpr(depth + 1, deeper_tp, rhsFilter: rhsFilter);
-        emit(')');
-        return;
-      }
+    if (dartType.binOps(tp).isEmpty) {
+      return emitLiteral(depth, tp);
     }
-    emit('(');
-    emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
-    emitBinaryOp(tp);
-    emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
-    emit(')');
+
+    String binop = oneOfSet(dartType.binOps(tp));
+    List<DartType> binOpParams = oneOfSet(dartType.binOpParameters(tp, binop));
+
+    // Avoid recursive assignments of the form a = a * 100.
+    if (binop == "*") {
+      rhsFilter?.consume();
+    }
+
+    // Reduce the number of operations of type growable * large value
+    // as these might lead to timeouts and/or oom errors.
+    if (binop == "*" &&
+        DartType.isGrowableType(binOpParams[0]) &&
+        dartType.isInterfaceOfType(binOpParams[1], DartType.NUM)) {
+      emit('(');
+      emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
+      emit(' $binop ');
+      emitLiteral(depth + 1, binOpParams[1], smallPositiveValue: true);
+      emit(')');
+    } else if (binop == "*" &&
+        DartType.isGrowableType(binOpParams[1]) &&
+        dartType.isInterfaceOfType(binOpParams[0], DartType.NUM)) {
+      emit('(');
+      emitLiteral(depth + 1, binOpParams[0], smallPositiveValue: true);
+      emit(' $binop ');
+      emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
+      emit(')');
+    } else {
+      emit('(');
+      emitExpr(depth + 1, binOpParams[0], rhsFilter: rhsFilter);
+      emit(' $binop ');
+      emitExpr(depth + 1, binOpParams[1], rhsFilter: rhsFilter);
+      emit(')');
+    }
   }
 
   // Emit expression with ternary operator: (b ? x : y)
@@ -1295,7 +1439,13 @@
   // Emit library call.
   void emitLibraryCall(int depth, DartType tp, {RhsFilter rhsFilter}) {
     DartLib lib = getLibraryMethod(tp);
-    final String proto = lib.proto;
+    if (lib == null) {
+      // no matching lib: resort to literal.
+      emitLiteral(depth + 1, tp, rhsFilter: rhsFilter);
+      return;
+    }
+    emit('(');
+    String proto = lib.proto;
     // Receiver.
     if (proto[0] != 'V') {
       emit('(');
@@ -1317,6 +1467,11 @@
       }
       emit(')');
     }
+    // Add cast to avoid error of double or int being interpreted as num.
+    if (dartType.isInterfaceOfType(tp, DartType.NUM)) {
+      emit(' as ${tp.name}');
+    }
+    emit(')');
   }
 
   // Emit call to a specific method.
@@ -1422,77 +1577,6 @@
   // Operators.
   //
 
-  // Emit same type in-out assignment operator.
-  String emitAssignOp(DartType tp) {
-    if (tp == DartType.INT) {
-      final assignOp = oneOf(const <String>[
-        ' += ',
-        ' -= ',
-        ' *= ',
-        ' ~/= ',
-        ' %= ',
-        ' &= ',
-        ' |= ',
-        ' ^= ',
-        ' >>= ',
-        ' <<= ',
-        ' ??= ',
-        ' = '
-      ]);
-      emit(assignOp);
-      return assignOp;
-    } else if (tp == DartType.DOUBLE) {
-      final assignOp =
-          oneOf(const <String>[' += ', ' -= ', ' *= ', ' /= ', ' ??= ', ' = ']);
-      emit(assignOp);
-      return assignOp;
-    } else {
-      final assignOp = oneOf(const <String>[' ??= ', ' = ']);
-      emit(assignOp);
-      return assignOp;
-    }
-  }
-
-  // Emit same type in-out unary operator.
-  void emitUnaryOp(DartType tp) {
-    if (tp == DartType.BOOL) {
-      emit('!');
-    } else if (tp == DartType.INT) {
-      emit(oneOf(const <String>['-', '~']));
-    } else if (tp == DartType.DOUBLE) {
-      emit('-');
-    } else {
-      assert(false);
-    }
-  }
-
-  // Emit same type in-out binary operator.
-  void emitBinaryOp(DartType tp) {
-    if (tp == DartType.BOOL) {
-      emit(oneOf(const <String>[' && ', ' || ']));
-    } else if (tp == DartType.INT) {
-      emit(oneOf(const <String>[
-        ' + ',
-        ' - ',
-        ' * ',
-        ' ~/ ',
-        ' % ',
-        ' & ',
-        ' | ',
-        ' ^ ',
-        ' >> ',
-        ' << ',
-        ' ?? '
-      ]));
-    } else if (tp == DartType.DOUBLE) {
-      emit(oneOf(const <String>[' + ', ' - ', ' * ', ' / ', ' ?? ']));
-    } else if (tp == DartType.STRING || tp == DartType.INT_LIST) {
-      emit(oneOf(const <String>[' + ', ' ?? ']));
-    } else {
-      emit(' ?? ');
-    }
-  }
-
   // Emit same type in-out increment operator.
   void emitPreOrPostOp(DartType tp) {
     if (tp == DartType.INT) {
@@ -1524,15 +1608,16 @@
     } else if (tp == DartType.DOUBLE) {
       return oneOf(api.doubleLibs);
     } else if (tp == DartType.STRING) {
-      return oneOf(api.stringLibs);
-    } else if (tp == DartType.INT_LIST) {
-      return oneOf(api.listLibs);
-    } else if (tp == DartType.INT_SET) {
-      return oneOf(api.setLibs);
-    } else if (tp == DartType.INT_STRING_MAP) {
-      return oneOf(api.mapLibs);
+      return oneOf(DartLib.stringLibs);
+    } else if (tp == DartType.LIST_INT) {
+      return oneOf(DartLib.listLibs);
+    } else if (tp == DartType.SET_INT) {
+      return oneOf(DartLib.setLibs);
+    } else if (tp == DartType.MAP_INT_STRING) {
+      return oneOf(DartLib.mapLibs);
     }
-    throw ArgumentError('Invalid DartType: $tp');
+    // No library method available that returns this type.
+    return null;
   }
 
   // Emit a library argument, possibly subject to restrictions.
@@ -1557,13 +1642,13 @@
         emitString(length: 2);
         break;
       case 'L':
-        emitExpr(depth, DartType.INT_LIST, rhsFilter: rhsFilter);
+        emitExpr(depth, DartType.LIST_INT, rhsFilter: rhsFilter);
         break;
       case 'X':
-        emitExpr(depth, DartType.INT_SET, rhsFilter: rhsFilter);
+        emitExpr(depth, DartType.SET_INT, rhsFilter: rhsFilter);
         break;
       case 'M':
-        emitExpr(depth, DartType.INT_STRING_MAP, rhsFilter: rhsFilter);
+        emitExpr(depth, DartType.MAP_INT_STRING, rhsFilter: rhsFilter);
         break;
       default:
         throw ArgumentError('Invalid p value: $p');
@@ -1573,34 +1658,13 @@
   //
   // Types.
   //
-
-  // Get a random value type.
-  DartType getType() {
-    switch (rand.nextInt(7)) {
-      case 0:
-        return DartType.BOOL;
-      case 1:
-        return DartType.INT;
-      case 2:
-        return fp ? DartType.DOUBLE : DartType.INT;
-      case 3:
-        return DartType.STRING;
-      case 4:
-        return DartType.INT_LIST;
-      case 5:
-        return DartType.INT_SET;
-      default:
-        return DartType.INT_STRING_MAP;
-    }
-  }
-
   List<DartType> fillTypes1({int limit = 4, bool isFfi = false}) {
     final list = <DartType>[];
     for (int i = 0, n = 1 + rand.nextInt(limit); i < n; i++) {
       if (isFfi) {
         list.add(fp ? oneOf([DartType.INT, DartType.DOUBLE]) : DartType.INT);
       } else {
-        list.add(getType());
+        list.add(oneOfSet(dartType.allTypes));
       }
     }
     return list;
@@ -1692,6 +1756,10 @@
     return choices[rand.nextInt(choices.length)];
   }
 
+  T oneOfSet<T>(Set<T> choices) {
+    return choices.elementAt(rand.nextInt(choices.length));
+  }
+
   // Special return code to handle oom errors.
   static const oomExitCode = 254;
 
@@ -1704,6 +1772,9 @@
   // Enables FFI method calls.
   final bool ffi;
 
+  // Disables nested types.
+  final bool flatTp;
+
   // File used for output.
   final RandomAccessFile file;
 
@@ -1717,6 +1788,9 @@
   int currentClass;
   int currentMethod;
 
+  // DartType instance.
+  DartType dartType;
+
   // Types of local variables currently in scope.
   List<DartType> localVars;
 
@@ -1753,6 +1827,56 @@
   bool skipExprCntr;
   int stmtCntr;
   int exprCntr;
+
+  // Interesting characters.
+  static const List<String> interestingChars = [
+    '\\u2665',
+    '\\u{1f600}', // rune
+  ];
+
+  // Regular characters.
+  static const regularChars =
+      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+- ';
+
+  // Interesting integer values.
+  static const List<int> interestingIntegers = [
+    0x0000000000000000,
+    0x0000000000000001,
+    0x000000007fffffff,
+    0x0000000080000000,
+    0x0000000080000001,
+    0x00000000ffffffff,
+    0x0000000100000000,
+    0x0000000100000001,
+    0x000000017fffffff,
+    0x0000000180000000,
+    0x0000000180000001,
+    0x00000001ffffffff,
+    0x7fffffff00000000,
+    0x7fffffff00000001,
+    0x7fffffff7fffffff,
+    0x7fffffff80000000,
+    0x7fffffff80000001,
+    0x7fffffffffffffff,
+    0x8000000000000000,
+    0x8000000000000001,
+    0x800000007fffffff,
+    0x8000000080000000,
+    0x8000000080000001,
+    0x80000000ffffffff,
+    0x8000000100000000,
+    0x8000000100000001,
+    0x800000017fffffff,
+    0x8000000180000000,
+    0x8000000180000001,
+    0x80000001ffffffff,
+    0xffffffff00000000,
+    0xffffffff00000001,
+    0xffffffff7fffffff,
+    0xffffffff80000000,
+    0xffffffff80000001,
+    0xffffffffffffffff
+  ];
 }
 
 // Generate seed. By default (no user-defined nonzero seed given),
@@ -1777,6 +1901,8 @@
     ..addFlag('fp', help: 'enables floating-point operations', defaultsTo: true)
     ..addFlag('ffi',
         help: 'enables FFI method calls (default: off)', defaultsTo: false)
+    ..addFlag('flat',
+        help: 'enables flat types (default: off)', defaultsTo: false)
     // Minimization mode extensions.
     ..addFlag('mini',
         help: 'enables minimization mode (default: off)', defaultsTo: false)
@@ -1793,11 +1919,12 @@
     final seed = getSeed(results['seed']);
     final fp = results['fp'];
     final ffi = results['ffi'];
+    final flatTp = results['flat'];
     final file = File(results.rest.single).openSync(mode: FileMode.write);
     final minimize = results['mini'];
     final smask = BigInt.parse(results['smask']);
     final emask = BigInt.parse(results['emask']);
-    final dartFuzz = DartFuzz(seed, fp, ffi, file,
+    final dartFuzz = DartFuzz(seed, fp, ffi, flatTp, file,
         minimize: minimize, smask: smask, emask: emask);
     dartFuzz.run();
     file.closeSync();
diff --git a/runtime/tools/dartfuzz/dartfuzz_api_table.dart b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
index d516218..26e4852 100644
--- a/runtime/tools/dartfuzz/dartfuzz_api_table.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
@@ -33,761 +33,761 @@
   const DartLib(this.name, this.proto);
 
   static const boolLibs = [
+    DartLib('NetworkInterface.listSupported', 'Vv'),
+    DartLib('SecurityContext.alpnSupported', 'Vv'),
+    DartLib('add', 'XI'),
     DartLib('bool.fromEnvironment', 'VS'),
-    DartLib('isEven', 'Iv'),
-    DartLib('isOdd', 'Iv'),
+    DartLib('endsWith', 'SS'),
     DartLib('isEmpty', 'Mv'),
-    DartLib('isNotEmpty', 'Mv'),
+    DartLib('isEmpty', 'Sv'),
+    DartLib('isEven', 'Iv'),
+    DartLib('isFinite', 'Dv'),
+    DartLib('isInfinite', 'Dv'),
     DartLib('isNaN', 'Dv'),
     DartLib('isNegative', 'Dv'),
-    DartLib('isInfinite', 'Dv'),
-    DartLib('isFinite', 'Dv'),
-    DartLib('add', 'XI'),
-    DartLib('endsWith', 'SS'),
-    DartLib('isEmpty', 'Sv'),
+    DartLib('isNotEmpty', 'Mv'),
     DartLib('isNotEmpty', 'Sv'),
-    DartLib('SecurityContext.alpnSupported', 'Vv'),
-    DartLib('NetworkInterface.listSupported', 'Vv'),
+    DartLib('isOdd', 'Iv'),
   ];
   static const intLibs = [
-    DartLib('JsonUtf8Encoder.DEFAULT_BUFFER_SIZE', 'Vv'),
-    DartLib('unicodeReplacementCharacterRune', 'Vv'),
-    DartLib('unicodeBomCharacterRune', 'Vv'),
+    DartLib('DateTime.april', 'Vv'),
+    DartLib('DateTime.august', 'Vv'),
+    DartLib('DateTime.daysPerWeek', 'Vv'),
+    DartLib('DateTime.december', 'Vv'),
+    DartLib('DateTime.february', 'Vv'),
+    DartLib('DateTime.friday', 'Vv'),
+    DartLib('DateTime.january', 'Vv'),
+    DartLib('DateTime.july', 'Vv'),
+    DartLib('DateTime.june', 'Vv'),
+    DartLib('DateTime.march', 'Vv'),
+    DartLib('DateTime.may', 'Vv'),
     DartLib('DateTime.monday', 'Vv'),
+    DartLib('DateTime.monthsPerYear', 'Vv'),
+    DartLib('DateTime.november', 'Vv'),
+    DartLib('DateTime.october', 'Vv'),
+    DartLib('DateTime.saturday', 'Vv'),
+    DartLib('DateTime.september', 'Vv'),
+    DartLib('DateTime.sunday', 'Vv'),
+    DartLib('DateTime.thursday', 'Vv'),
     DartLib('DateTime.tuesday', 'Vv'),
     DartLib('DateTime.wednesday', 'Vv'),
-    DartLib('DateTime.thursday', 'Vv'),
-    DartLib('DateTime.friday', 'Vv'),
-    DartLib('DateTime.saturday', 'Vv'),
-    DartLib('DateTime.sunday', 'Vv'),
-    DartLib('DateTime.daysPerWeek', 'Vv'),
-    DartLib('DateTime.january', 'Vv'),
-    DartLib('DateTime.february', 'Vv'),
-    DartLib('DateTime.march', 'Vv'),
-    DartLib('DateTime.april', 'Vv'),
-    DartLib('DateTime.may', 'Vv'),
-    DartLib('DateTime.june', 'Vv'),
-    DartLib('DateTime.july', 'Vv'),
-    DartLib('DateTime.august', 'Vv'),
-    DartLib('DateTime.september', 'Vv'),
-    DartLib('DateTime.october', 'Vv'),
-    DartLib('DateTime.november', 'Vv'),
-    DartLib('DateTime.december', 'Vv'),
-    DartLib('DateTime.monthsPerYear', 'Vv'),
-    DartLib('round', 'DV'),
-    DartLib('floor', 'DV'),
-    DartLib('ceil', 'DV'),
-    DartLib('truncate', 'DV'),
-    DartLib('Duration.microsecondsPerMillisecond', 'Vv'),
-    DartLib('Duration.millisecondsPerSecond', 'Vv'),
-    DartLib('Duration.secondsPerMinute', 'Vv'),
-    DartLib('Duration.minutesPerHour', 'Vv'),
     DartLib('Duration.hoursPerDay', 'Vv'),
-    DartLib('Duration.microsecondsPerSecond', 'Vv'),
-    DartLib('Duration.microsecondsPerMinute', 'Vv'),
-    DartLib('Duration.microsecondsPerHour', 'Vv'),
     DartLib('Duration.microsecondsPerDay', 'Vv'),
-    DartLib('Duration.millisecondsPerMinute', 'Vv'),
-    DartLib('Duration.millisecondsPerHour', 'Vv'),
+    DartLib('Duration.microsecondsPerHour', 'Vv'),
+    DartLib('Duration.microsecondsPerMillisecond', 'Vv'),
+    DartLib('Duration.microsecondsPerMinute', 'Vv'),
+    DartLib('Duration.microsecondsPerSecond', 'Vv'),
     DartLib('Duration.millisecondsPerDay', 'Vv'),
-    DartLib('Duration.secondsPerHour', 'Vv'),
-    DartLib('Duration.secondsPerDay', 'Vv'),
+    DartLib('Duration.millisecondsPerHour', 'Vv'),
+    DartLib('Duration.millisecondsPerMinute', 'Vv'),
+    DartLib('Duration.millisecondsPerSecond', 'Vv'),
     DartLib('Duration.minutesPerDay', 'Vv'),
-    DartLib('RangeError.checkValidRange', 'VIIISSS'),
-    DartLib('int.fromEnvironment', 'VS'),
-    DartLib('modPow', 'III'),
-    DartLib('modInverse', 'II'),
-    DartLib('gcd', 'II'),
-    DartLib('toUnsigned', 'II'),
-    DartLib('toSigned', 'II'),
-    DartLib('abs', 'IV'),
-    DartLib('round', 'IV'),
-    DartLib('floor', 'IV'),
-    DartLib('ceil', 'IV'),
-    DartLib('truncate', 'IV'),
-    DartLib('int.parse', 'VS'),
-    DartLib('int.tryParse', 'VS'),
-    DartLib('bitLength', 'Iv'),
-    DartLib('sign', 'Iv'),
-    DartLib('indexOf', 'LII'),
-    DartLib('lastIndexOf', 'LII'),
-    DartLib('removeAt', 'LI'),
-    DartLib('removeLast', 'LV'),
-    DartLib('length', 'Lv'),
-    DartLib('length', 'Mv'),
-    DartLib('compareTo', 'DD'),
-    DartLib('round', 'DV'),
-    DartLib('floor', 'DV'),
-    DartLib('ceil', 'DV'),
-    DartLib('truncate', 'DV'),
-    DartLib('toInt', 'DV'),
-    DartLib('codeUnitAt', 'SI'),
-    DartLib('compareTo', 'SS'),
-    DartLib('length', 'Sv'),
-    DartLib('OSError.noErrorCode', 'Vv'),
-    DartLib('ZLibOption.minWindowBits', 'Vv'),
-    DartLib('ZLibOption.MIN_WINDOW_BITS', 'Vv'),
-    DartLib('ZLibOption.maxWindowBits', 'Vv'),
-    DartLib('ZLibOption.MAX_WINDOW_BITS', 'Vv'),
-    DartLib('ZLibOption.defaultWindowBits', 'Vv'),
-    DartLib('ZLibOption.DEFAULT_WINDOW_BITS', 'Vv'),
-    DartLib('ZLibOption.minLevel', 'Vv'),
-    DartLib('ZLibOption.MIN_LEVEL', 'Vv'),
-    DartLib('ZLibOption.maxLevel', 'Vv'),
-    DartLib('ZLibOption.MAX_LEVEL', 'Vv'),
-    DartLib('ZLibOption.defaultLevel', 'Vv'),
-    DartLib('ZLibOption.DEFAULT_LEVEL', 'Vv'),
-    DartLib('ZLibOption.minMemLevel', 'Vv'),
-    DartLib('ZLibOption.MIN_MEM_LEVEL', 'Vv'),
-    DartLib('ZLibOption.maxMemLevel', 'Vv'),
-    DartLib('ZLibOption.MAX_MEM_LEVEL', 'Vv'),
-    DartLib('ZLibOption.defaultMemLevel', 'Vv'),
-    DartLib('ZLibOption.DEFAULT_MEM_LEVEL', 'Vv'),
-    DartLib('ZLibOption.strategyFiltered', 'Vv'),
-    DartLib('ZLibOption.STRATEGY_FILTERED', 'Vv'),
-    DartLib('ZLibOption.strategyHuffmanOnly', 'Vv'),
-    DartLib('ZLibOption.STRATEGY_HUFFMAN_ONLY', 'Vv'),
-    DartLib('ZLibOption.strategyRle', 'Vv'),
-    DartLib('ZLibOption.STRATEGY_RLE', 'Vv'),
-    DartLib('ZLibOption.strategyFixed', 'Vv'),
-    DartLib('ZLibOption.STRATEGY_FIXED', 'Vv'),
-    DartLib('ZLibOption.strategyDefault', 'Vv'),
-    DartLib('ZLibOption.STRATEGY_DEFAULT', 'Vv'),
-    DartLib('RawSocketOption.levelSocket', 'Vv'),
-    DartLib('RawSocketOption.levelIPv4', 'Vv'),
-    DartLib('RawSocketOption.IPv4MulticastInterface', 'Vv'),
-    DartLib('RawSocketOption.levelIPv6', 'Vv'),
-    DartLib('RawSocketOption.IPv6MulticastInterface', 'Vv'),
-    DartLib('RawSocketOption.levelTcp', 'Vv'),
-    DartLib('RawSocketOption.levelUdp', 'Vv'),
-    DartLib('Isolate.immediate', 'Vv'),
-    DartLib('Isolate.beforeNextEvent', 'Vv'),
-    DartLib('Int8List.bytesPerElement', 'Vv'),
-    DartLib('Uint8List.bytesPerElement', 'Vv'),
-    DartLib('Uint8ClampedList.bytesPerElement', 'Vv'),
-    DartLib('Int16List.bytesPerElement', 'Vv'),
-    DartLib('Uint16List.bytesPerElement', 'Vv'),
-    DartLib('Int32List.bytesPerElement', 'Vv'),
-    DartLib('Uint32List.bytesPerElement', 'Vv'),
-    DartLib('Int64List.bytesPerElement', 'Vv'),
-    DartLib('Uint64List.bytesPerElement', 'Vv'),
+    DartLib('Duration.minutesPerHour', 'Vv'),
+    DartLib('Duration.secondsPerDay', 'Vv'),
+    DartLib('Duration.secondsPerHour', 'Vv'),
+    DartLib('Duration.secondsPerMinute', 'Vv'),
     DartLib('Float32List.bytesPerElement', 'Vv'),
-    DartLib('Float64List.bytesPerElement', 'Vv'),
-    DartLib('Float32x4List.bytesPerElement', 'Vv'),
-    DartLib('Int32x4List.bytesPerElement', 'Vv'),
-    DartLib('Float64x2List.bytesPerElement', 'Vv'),
-    DartLib('Float32x4.xxxx', 'Vv'),
-    DartLib('Float32x4.xxxy', 'Vv'),
-    DartLib('Float32x4.xxxz', 'Vv'),
-    DartLib('Float32x4.xxxw', 'Vv'),
-    DartLib('Float32x4.xxyx', 'Vv'),
-    DartLib('Float32x4.xxyy', 'Vv'),
-    DartLib('Float32x4.xxyz', 'Vv'),
-    DartLib('Float32x4.xxyw', 'Vv'),
-    DartLib('Float32x4.xxzx', 'Vv'),
-    DartLib('Float32x4.xxzy', 'Vv'),
-    DartLib('Float32x4.xxzz', 'Vv'),
-    DartLib('Float32x4.xxzw', 'Vv'),
-    DartLib('Float32x4.xxwx', 'Vv'),
-    DartLib('Float32x4.xxwy', 'Vv'),
-    DartLib('Float32x4.xxwz', 'Vv'),
-    DartLib('Float32x4.xxww', 'Vv'),
-    DartLib('Float32x4.xyxx', 'Vv'),
-    DartLib('Float32x4.xyxy', 'Vv'),
-    DartLib('Float32x4.xyxz', 'Vv'),
-    DartLib('Float32x4.xyxw', 'Vv'),
-    DartLib('Float32x4.xyyx', 'Vv'),
-    DartLib('Float32x4.xyyy', 'Vv'),
-    DartLib('Float32x4.xyyz', 'Vv'),
-    DartLib('Float32x4.xyyw', 'Vv'),
-    DartLib('Float32x4.xyzx', 'Vv'),
-    DartLib('Float32x4.xyzy', 'Vv'),
-    DartLib('Float32x4.xyzz', 'Vv'),
-    DartLib('Float32x4.xyzw', 'Vv'),
-    DartLib('Float32x4.xywx', 'Vv'),
-    DartLib('Float32x4.xywy', 'Vv'),
-    DartLib('Float32x4.xywz', 'Vv'),
-    DartLib('Float32x4.xyww', 'Vv'),
-    DartLib('Float32x4.xzxx', 'Vv'),
-    DartLib('Float32x4.xzxy', 'Vv'),
-    DartLib('Float32x4.xzxz', 'Vv'),
-    DartLib('Float32x4.xzxw', 'Vv'),
-    DartLib('Float32x4.xzyx', 'Vv'),
-    DartLib('Float32x4.xzyy', 'Vv'),
-    DartLib('Float32x4.xzyz', 'Vv'),
-    DartLib('Float32x4.xzyw', 'Vv'),
-    DartLib('Float32x4.xzzx', 'Vv'),
-    DartLib('Float32x4.xzzy', 'Vv'),
-    DartLib('Float32x4.xzzz', 'Vv'),
-    DartLib('Float32x4.xzzw', 'Vv'),
-    DartLib('Float32x4.xzwx', 'Vv'),
-    DartLib('Float32x4.xzwy', 'Vv'),
-    DartLib('Float32x4.xzwz', 'Vv'),
-    DartLib('Float32x4.xzww', 'Vv'),
-    DartLib('Float32x4.xwxx', 'Vv'),
-    DartLib('Float32x4.xwxy', 'Vv'),
-    DartLib('Float32x4.xwxz', 'Vv'),
-    DartLib('Float32x4.xwxw', 'Vv'),
-    DartLib('Float32x4.xwyx', 'Vv'),
-    DartLib('Float32x4.xwyy', 'Vv'),
-    DartLib('Float32x4.xwyz', 'Vv'),
-    DartLib('Float32x4.xwyw', 'Vv'),
-    DartLib('Float32x4.xwzx', 'Vv'),
-    DartLib('Float32x4.xwzy', 'Vv'),
-    DartLib('Float32x4.xwzz', 'Vv'),
-    DartLib('Float32x4.xwzw', 'Vv'),
-    DartLib('Float32x4.xwwx', 'Vv'),
-    DartLib('Float32x4.xwwy', 'Vv'),
-    DartLib('Float32x4.xwwz', 'Vv'),
-    DartLib('Float32x4.xwww', 'Vv'),
-    DartLib('Float32x4.yxxx', 'Vv'),
-    DartLib('Float32x4.yxxy', 'Vv'),
-    DartLib('Float32x4.yxxz', 'Vv'),
-    DartLib('Float32x4.yxxw', 'Vv'),
-    DartLib('Float32x4.yxyx', 'Vv'),
-    DartLib('Float32x4.yxyy', 'Vv'),
-    DartLib('Float32x4.yxyz', 'Vv'),
-    DartLib('Float32x4.yxyw', 'Vv'),
-    DartLib('Float32x4.yxzx', 'Vv'),
-    DartLib('Float32x4.yxzy', 'Vv'),
-    DartLib('Float32x4.yxzz', 'Vv'),
-    DartLib('Float32x4.yxzw', 'Vv'),
-    DartLib('Float32x4.yxwx', 'Vv'),
-    DartLib('Float32x4.yxwy', 'Vv'),
-    DartLib('Float32x4.yxwz', 'Vv'),
-    DartLib('Float32x4.yxww', 'Vv'),
-    DartLib('Float32x4.yyxx', 'Vv'),
-    DartLib('Float32x4.yyxy', 'Vv'),
-    DartLib('Float32x4.yyxz', 'Vv'),
-    DartLib('Float32x4.yyxw', 'Vv'),
-    DartLib('Float32x4.yyyx', 'Vv'),
-    DartLib('Float32x4.yyyy', 'Vv'),
-    DartLib('Float32x4.yyyz', 'Vv'),
-    DartLib('Float32x4.yyyw', 'Vv'),
-    DartLib('Float32x4.yyzx', 'Vv'),
-    DartLib('Float32x4.yyzy', 'Vv'),
-    DartLib('Float32x4.yyzz', 'Vv'),
-    DartLib('Float32x4.yyzw', 'Vv'),
-    DartLib('Float32x4.yywx', 'Vv'),
-    DartLib('Float32x4.yywy', 'Vv'),
-    DartLib('Float32x4.yywz', 'Vv'),
-    DartLib('Float32x4.yyww', 'Vv'),
-    DartLib('Float32x4.yzxx', 'Vv'),
-    DartLib('Float32x4.yzxy', 'Vv'),
-    DartLib('Float32x4.yzxz', 'Vv'),
-    DartLib('Float32x4.yzxw', 'Vv'),
-    DartLib('Float32x4.yzyx', 'Vv'),
-    DartLib('Float32x4.yzyy', 'Vv'),
-    DartLib('Float32x4.yzyz', 'Vv'),
-    DartLib('Float32x4.yzyw', 'Vv'),
-    DartLib('Float32x4.yzzx', 'Vv'),
-    DartLib('Float32x4.yzzy', 'Vv'),
-    DartLib('Float32x4.yzzz', 'Vv'),
-    DartLib('Float32x4.yzzw', 'Vv'),
-    DartLib('Float32x4.yzwx', 'Vv'),
-    DartLib('Float32x4.yzwy', 'Vv'),
-    DartLib('Float32x4.yzwz', 'Vv'),
-    DartLib('Float32x4.yzww', 'Vv'),
-    DartLib('Float32x4.ywxx', 'Vv'),
-    DartLib('Float32x4.ywxy', 'Vv'),
-    DartLib('Float32x4.ywxz', 'Vv'),
-    DartLib('Float32x4.ywxw', 'Vv'),
-    DartLib('Float32x4.ywyx', 'Vv'),
-    DartLib('Float32x4.ywyy', 'Vv'),
-    DartLib('Float32x4.ywyz', 'Vv'),
-    DartLib('Float32x4.ywyw', 'Vv'),
-    DartLib('Float32x4.ywzx', 'Vv'),
-    DartLib('Float32x4.ywzy', 'Vv'),
-    DartLib('Float32x4.ywzz', 'Vv'),
-    DartLib('Float32x4.ywzw', 'Vv'),
-    DartLib('Float32x4.ywwx', 'Vv'),
-    DartLib('Float32x4.ywwy', 'Vv'),
-    DartLib('Float32x4.ywwz', 'Vv'),
-    DartLib('Float32x4.ywww', 'Vv'),
-    DartLib('Float32x4.zxxx', 'Vv'),
-    DartLib('Float32x4.zxxy', 'Vv'),
-    DartLib('Float32x4.zxxz', 'Vv'),
-    DartLib('Float32x4.zxxw', 'Vv'),
-    DartLib('Float32x4.zxyx', 'Vv'),
-    DartLib('Float32x4.zxyy', 'Vv'),
-    DartLib('Float32x4.zxyz', 'Vv'),
-    DartLib('Float32x4.zxyw', 'Vv'),
-    DartLib('Float32x4.zxzx', 'Vv'),
-    DartLib('Float32x4.zxzy', 'Vv'),
-    DartLib('Float32x4.zxzz', 'Vv'),
-    DartLib('Float32x4.zxzw', 'Vv'),
-    DartLib('Float32x4.zxwx', 'Vv'),
-    DartLib('Float32x4.zxwy', 'Vv'),
-    DartLib('Float32x4.zxwz', 'Vv'),
-    DartLib('Float32x4.zxww', 'Vv'),
-    DartLib('Float32x4.zyxx', 'Vv'),
-    DartLib('Float32x4.zyxy', 'Vv'),
-    DartLib('Float32x4.zyxz', 'Vv'),
-    DartLib('Float32x4.zyxw', 'Vv'),
-    DartLib('Float32x4.zyyx', 'Vv'),
-    DartLib('Float32x4.zyyy', 'Vv'),
-    DartLib('Float32x4.zyyz', 'Vv'),
-    DartLib('Float32x4.zyyw', 'Vv'),
-    DartLib('Float32x4.zyzx', 'Vv'),
-    DartLib('Float32x4.zyzy', 'Vv'),
-    DartLib('Float32x4.zyzz', 'Vv'),
-    DartLib('Float32x4.zyzw', 'Vv'),
-    DartLib('Float32x4.zywx', 'Vv'),
-    DartLib('Float32x4.zywy', 'Vv'),
-    DartLib('Float32x4.zywz', 'Vv'),
-    DartLib('Float32x4.zyww', 'Vv'),
-    DartLib('Float32x4.zzxx', 'Vv'),
-    DartLib('Float32x4.zzxy', 'Vv'),
-    DartLib('Float32x4.zzxz', 'Vv'),
-    DartLib('Float32x4.zzxw', 'Vv'),
-    DartLib('Float32x4.zzyx', 'Vv'),
-    DartLib('Float32x4.zzyy', 'Vv'),
-    DartLib('Float32x4.zzyz', 'Vv'),
-    DartLib('Float32x4.zzyw', 'Vv'),
-    DartLib('Float32x4.zzzx', 'Vv'),
-    DartLib('Float32x4.zzzy', 'Vv'),
-    DartLib('Float32x4.zzzz', 'Vv'),
-    DartLib('Float32x4.zzzw', 'Vv'),
-    DartLib('Float32x4.zzwx', 'Vv'),
-    DartLib('Float32x4.zzwy', 'Vv'),
-    DartLib('Float32x4.zzwz', 'Vv'),
-    DartLib('Float32x4.zzww', 'Vv'),
-    DartLib('Float32x4.zwxx', 'Vv'),
-    DartLib('Float32x4.zwxy', 'Vv'),
-    DartLib('Float32x4.zwxz', 'Vv'),
-    DartLib('Float32x4.zwxw', 'Vv'),
-    DartLib('Float32x4.zwyx', 'Vv'),
-    DartLib('Float32x4.zwyy', 'Vv'),
-    DartLib('Float32x4.zwyz', 'Vv'),
-    DartLib('Float32x4.zwyw', 'Vv'),
-    DartLib('Float32x4.zwzx', 'Vv'),
-    DartLib('Float32x4.zwzy', 'Vv'),
-    DartLib('Float32x4.zwzz', 'Vv'),
-    DartLib('Float32x4.zwzw', 'Vv'),
-    DartLib('Float32x4.zwwx', 'Vv'),
-    DartLib('Float32x4.zwwy', 'Vv'),
-    DartLib('Float32x4.zwwz', 'Vv'),
-    DartLib('Float32x4.zwww', 'Vv'),
-    DartLib('Float32x4.wxxx', 'Vv'),
-    DartLib('Float32x4.wxxy', 'Vv'),
-    DartLib('Float32x4.wxxz', 'Vv'),
-    DartLib('Float32x4.wxxw', 'Vv'),
-    DartLib('Float32x4.wxyx', 'Vv'),
-    DartLib('Float32x4.wxyy', 'Vv'),
-    DartLib('Float32x4.wxyz', 'Vv'),
-    DartLib('Float32x4.wxyw', 'Vv'),
-    DartLib('Float32x4.wxzx', 'Vv'),
-    DartLib('Float32x4.wxzy', 'Vv'),
-    DartLib('Float32x4.wxzz', 'Vv'),
-    DartLib('Float32x4.wxzw', 'Vv'),
-    DartLib('Float32x4.wxwx', 'Vv'),
-    DartLib('Float32x4.wxwy', 'Vv'),
-    DartLib('Float32x4.wxwz', 'Vv'),
-    DartLib('Float32x4.wxww', 'Vv'),
-    DartLib('Float32x4.wyxx', 'Vv'),
-    DartLib('Float32x4.wyxy', 'Vv'),
-    DartLib('Float32x4.wyxz', 'Vv'),
-    DartLib('Float32x4.wyxw', 'Vv'),
-    DartLib('Float32x4.wyyx', 'Vv'),
-    DartLib('Float32x4.wyyy', 'Vv'),
-    DartLib('Float32x4.wyyz', 'Vv'),
-    DartLib('Float32x4.wyyw', 'Vv'),
-    DartLib('Float32x4.wyzx', 'Vv'),
-    DartLib('Float32x4.wyzy', 'Vv'),
-    DartLib('Float32x4.wyzz', 'Vv'),
-    DartLib('Float32x4.wyzw', 'Vv'),
-    DartLib('Float32x4.wywx', 'Vv'),
-    DartLib('Float32x4.wywy', 'Vv'),
-    DartLib('Float32x4.wywz', 'Vv'),
-    DartLib('Float32x4.wyww', 'Vv'),
-    DartLib('Float32x4.wzxx', 'Vv'),
-    DartLib('Float32x4.wzxy', 'Vv'),
-    DartLib('Float32x4.wzxz', 'Vv'),
-    DartLib('Float32x4.wzxw', 'Vv'),
-    DartLib('Float32x4.wzyx', 'Vv'),
-    DartLib('Float32x4.wzyy', 'Vv'),
-    DartLib('Float32x4.wzyz', 'Vv'),
-    DartLib('Float32x4.wzyw', 'Vv'),
-    DartLib('Float32x4.wzzx', 'Vv'),
-    DartLib('Float32x4.wzzy', 'Vv'),
-    DartLib('Float32x4.wzzz', 'Vv'),
-    DartLib('Float32x4.wzzw', 'Vv'),
-    DartLib('Float32x4.wzwx', 'Vv'),
-    DartLib('Float32x4.wzwy', 'Vv'),
-    DartLib('Float32x4.wzwz', 'Vv'),
-    DartLib('Float32x4.wzww', 'Vv'),
-    DartLib('Float32x4.wwxx', 'Vv'),
-    DartLib('Float32x4.wwxy', 'Vv'),
-    DartLib('Float32x4.wwxz', 'Vv'),
-    DartLib('Float32x4.wwxw', 'Vv'),
-    DartLib('Float32x4.wwyx', 'Vv'),
-    DartLib('Float32x4.wwyy', 'Vv'),
-    DartLib('Float32x4.wwyz', 'Vv'),
-    DartLib('Float32x4.wwyw', 'Vv'),
-    DartLib('Float32x4.wwzx', 'Vv'),
-    DartLib('Float32x4.wwzy', 'Vv'),
-    DartLib('Float32x4.wwzz', 'Vv'),
-    DartLib('Float32x4.wwzw', 'Vv'),
+    DartLib('Float32x4.wwww', 'Vv'),
     DartLib('Float32x4.wwwx', 'Vv'),
     DartLib('Float32x4.wwwy', 'Vv'),
     DartLib('Float32x4.wwwz', 'Vv'),
-    DartLib('Float32x4.wwww', 'Vv'),
-    DartLib('Int32x4.xxxx', 'Vv'),
-    DartLib('Int32x4.xxxy', 'Vv'),
-    DartLib('Int32x4.xxxz', 'Vv'),
-    DartLib('Int32x4.xxxw', 'Vv'),
-    DartLib('Int32x4.xxyx', 'Vv'),
-    DartLib('Int32x4.xxyy', 'Vv'),
-    DartLib('Int32x4.xxyz', 'Vv'),
-    DartLib('Int32x4.xxyw', 'Vv'),
-    DartLib('Int32x4.xxzx', 'Vv'),
-    DartLib('Int32x4.xxzy', 'Vv'),
-    DartLib('Int32x4.xxzz', 'Vv'),
-    DartLib('Int32x4.xxzw', 'Vv'),
-    DartLib('Int32x4.xxwx', 'Vv'),
-    DartLib('Int32x4.xxwy', 'Vv'),
-    DartLib('Int32x4.xxwz', 'Vv'),
-    DartLib('Int32x4.xxww', 'Vv'),
-    DartLib('Int32x4.xyxx', 'Vv'),
-    DartLib('Int32x4.xyxy', 'Vv'),
-    DartLib('Int32x4.xyxz', 'Vv'),
-    DartLib('Int32x4.xyxw', 'Vv'),
-    DartLib('Int32x4.xyyx', 'Vv'),
-    DartLib('Int32x4.xyyy', 'Vv'),
-    DartLib('Int32x4.xyyz', 'Vv'),
-    DartLib('Int32x4.xyyw', 'Vv'),
-    DartLib('Int32x4.xyzx', 'Vv'),
-    DartLib('Int32x4.xyzy', 'Vv'),
-    DartLib('Int32x4.xyzz', 'Vv'),
-    DartLib('Int32x4.xyzw', 'Vv'),
-    DartLib('Int32x4.xywx', 'Vv'),
-    DartLib('Int32x4.xywy', 'Vv'),
-    DartLib('Int32x4.xywz', 'Vv'),
-    DartLib('Int32x4.xyww', 'Vv'),
-    DartLib('Int32x4.xzxx', 'Vv'),
-    DartLib('Int32x4.xzxy', 'Vv'),
-    DartLib('Int32x4.xzxz', 'Vv'),
-    DartLib('Int32x4.xzxw', 'Vv'),
-    DartLib('Int32x4.xzyx', 'Vv'),
-    DartLib('Int32x4.xzyy', 'Vv'),
-    DartLib('Int32x4.xzyz', 'Vv'),
-    DartLib('Int32x4.xzyw', 'Vv'),
-    DartLib('Int32x4.xzzx', 'Vv'),
-    DartLib('Int32x4.xzzy', 'Vv'),
-    DartLib('Int32x4.xzzz', 'Vv'),
-    DartLib('Int32x4.xzzw', 'Vv'),
-    DartLib('Int32x4.xzwx', 'Vv'),
-    DartLib('Int32x4.xzwy', 'Vv'),
-    DartLib('Int32x4.xzwz', 'Vv'),
-    DartLib('Int32x4.xzww', 'Vv'),
-    DartLib('Int32x4.xwxx', 'Vv'),
-    DartLib('Int32x4.xwxy', 'Vv'),
-    DartLib('Int32x4.xwxz', 'Vv'),
-    DartLib('Int32x4.xwxw', 'Vv'),
-    DartLib('Int32x4.xwyx', 'Vv'),
-    DartLib('Int32x4.xwyy', 'Vv'),
-    DartLib('Int32x4.xwyz', 'Vv'),
-    DartLib('Int32x4.xwyw', 'Vv'),
-    DartLib('Int32x4.xwzx', 'Vv'),
-    DartLib('Int32x4.xwzy', 'Vv'),
-    DartLib('Int32x4.xwzz', 'Vv'),
-    DartLib('Int32x4.xwzw', 'Vv'),
-    DartLib('Int32x4.xwwx', 'Vv'),
-    DartLib('Int32x4.xwwy', 'Vv'),
-    DartLib('Int32x4.xwwz', 'Vv'),
-    DartLib('Int32x4.xwww', 'Vv'),
-    DartLib('Int32x4.yxxx', 'Vv'),
-    DartLib('Int32x4.yxxy', 'Vv'),
-    DartLib('Int32x4.yxxz', 'Vv'),
-    DartLib('Int32x4.yxxw', 'Vv'),
-    DartLib('Int32x4.yxyx', 'Vv'),
-    DartLib('Int32x4.yxyy', 'Vv'),
-    DartLib('Int32x4.yxyz', 'Vv'),
-    DartLib('Int32x4.yxyw', 'Vv'),
-    DartLib('Int32x4.yxzx', 'Vv'),
-    DartLib('Int32x4.yxzy', 'Vv'),
-    DartLib('Int32x4.yxzz', 'Vv'),
-    DartLib('Int32x4.yxzw', 'Vv'),
-    DartLib('Int32x4.yxwx', 'Vv'),
-    DartLib('Int32x4.yxwy', 'Vv'),
-    DartLib('Int32x4.yxwz', 'Vv'),
-    DartLib('Int32x4.yxww', 'Vv'),
-    DartLib('Int32x4.yyxx', 'Vv'),
-    DartLib('Int32x4.yyxy', 'Vv'),
-    DartLib('Int32x4.yyxz', 'Vv'),
-    DartLib('Int32x4.yyxw', 'Vv'),
-    DartLib('Int32x4.yyyx', 'Vv'),
-    DartLib('Int32x4.yyyy', 'Vv'),
-    DartLib('Int32x4.yyyz', 'Vv'),
-    DartLib('Int32x4.yyyw', 'Vv'),
-    DartLib('Int32x4.yyzx', 'Vv'),
-    DartLib('Int32x4.yyzy', 'Vv'),
-    DartLib('Int32x4.yyzz', 'Vv'),
-    DartLib('Int32x4.yyzw', 'Vv'),
-    DartLib('Int32x4.yywx', 'Vv'),
-    DartLib('Int32x4.yywy', 'Vv'),
-    DartLib('Int32x4.yywz', 'Vv'),
-    DartLib('Int32x4.yyww', 'Vv'),
-    DartLib('Int32x4.yzxx', 'Vv'),
-    DartLib('Int32x4.yzxy', 'Vv'),
-    DartLib('Int32x4.yzxz', 'Vv'),
-    DartLib('Int32x4.yzxw', 'Vv'),
-    DartLib('Int32x4.yzyx', 'Vv'),
-    DartLib('Int32x4.yzyy', 'Vv'),
-    DartLib('Int32x4.yzyz', 'Vv'),
-    DartLib('Int32x4.yzyw', 'Vv'),
-    DartLib('Int32x4.yzzx', 'Vv'),
-    DartLib('Int32x4.yzzy', 'Vv'),
-    DartLib('Int32x4.yzzz', 'Vv'),
-    DartLib('Int32x4.yzzw', 'Vv'),
-    DartLib('Int32x4.yzwx', 'Vv'),
-    DartLib('Int32x4.yzwy', 'Vv'),
-    DartLib('Int32x4.yzwz', 'Vv'),
-    DartLib('Int32x4.yzww', 'Vv'),
-    DartLib('Int32x4.ywxx', 'Vv'),
-    DartLib('Int32x4.ywxy', 'Vv'),
-    DartLib('Int32x4.ywxz', 'Vv'),
-    DartLib('Int32x4.ywxw', 'Vv'),
-    DartLib('Int32x4.ywyx', 'Vv'),
-    DartLib('Int32x4.ywyy', 'Vv'),
-    DartLib('Int32x4.ywyz', 'Vv'),
-    DartLib('Int32x4.ywyw', 'Vv'),
-    DartLib('Int32x4.ywzx', 'Vv'),
-    DartLib('Int32x4.ywzy', 'Vv'),
-    DartLib('Int32x4.ywzz', 'Vv'),
-    DartLib('Int32x4.ywzw', 'Vv'),
-    DartLib('Int32x4.ywwx', 'Vv'),
-    DartLib('Int32x4.ywwy', 'Vv'),
-    DartLib('Int32x4.ywwz', 'Vv'),
-    DartLib('Int32x4.ywww', 'Vv'),
-    DartLib('Int32x4.zxxx', 'Vv'),
-    DartLib('Int32x4.zxxy', 'Vv'),
-    DartLib('Int32x4.zxxz', 'Vv'),
-    DartLib('Int32x4.zxxw', 'Vv'),
-    DartLib('Int32x4.zxyx', 'Vv'),
-    DartLib('Int32x4.zxyy', 'Vv'),
-    DartLib('Int32x4.zxyz', 'Vv'),
-    DartLib('Int32x4.zxyw', 'Vv'),
-    DartLib('Int32x4.zxzx', 'Vv'),
-    DartLib('Int32x4.zxzy', 'Vv'),
-    DartLib('Int32x4.zxzz', 'Vv'),
-    DartLib('Int32x4.zxzw', 'Vv'),
-    DartLib('Int32x4.zxwx', 'Vv'),
-    DartLib('Int32x4.zxwy', 'Vv'),
-    DartLib('Int32x4.zxwz', 'Vv'),
-    DartLib('Int32x4.zxww', 'Vv'),
-    DartLib('Int32x4.zyxx', 'Vv'),
-    DartLib('Int32x4.zyxy', 'Vv'),
-    DartLib('Int32x4.zyxz', 'Vv'),
-    DartLib('Int32x4.zyxw', 'Vv'),
-    DartLib('Int32x4.zyyx', 'Vv'),
-    DartLib('Int32x4.zyyy', 'Vv'),
-    DartLib('Int32x4.zyyz', 'Vv'),
-    DartLib('Int32x4.zyyw', 'Vv'),
-    DartLib('Int32x4.zyzx', 'Vv'),
-    DartLib('Int32x4.zyzy', 'Vv'),
-    DartLib('Int32x4.zyzz', 'Vv'),
-    DartLib('Int32x4.zyzw', 'Vv'),
-    DartLib('Int32x4.zywx', 'Vv'),
-    DartLib('Int32x4.zywy', 'Vv'),
-    DartLib('Int32x4.zywz', 'Vv'),
-    DartLib('Int32x4.zyww', 'Vv'),
-    DartLib('Int32x4.zzxx', 'Vv'),
-    DartLib('Int32x4.zzxy', 'Vv'),
-    DartLib('Int32x4.zzxz', 'Vv'),
-    DartLib('Int32x4.zzxw', 'Vv'),
-    DartLib('Int32x4.zzyx', 'Vv'),
-    DartLib('Int32x4.zzyy', 'Vv'),
-    DartLib('Int32x4.zzyz', 'Vv'),
-    DartLib('Int32x4.zzyw', 'Vv'),
-    DartLib('Int32x4.zzzx', 'Vv'),
-    DartLib('Int32x4.zzzy', 'Vv'),
-    DartLib('Int32x4.zzzz', 'Vv'),
-    DartLib('Int32x4.zzzw', 'Vv'),
-    DartLib('Int32x4.zzwx', 'Vv'),
-    DartLib('Int32x4.zzwy', 'Vv'),
-    DartLib('Int32x4.zzwz', 'Vv'),
-    DartLib('Int32x4.zzww', 'Vv'),
-    DartLib('Int32x4.zwxx', 'Vv'),
-    DartLib('Int32x4.zwxy', 'Vv'),
-    DartLib('Int32x4.zwxz', 'Vv'),
-    DartLib('Int32x4.zwxw', 'Vv'),
-    DartLib('Int32x4.zwyx', 'Vv'),
-    DartLib('Int32x4.zwyy', 'Vv'),
-    DartLib('Int32x4.zwyz', 'Vv'),
-    DartLib('Int32x4.zwyw', 'Vv'),
-    DartLib('Int32x4.zwzx', 'Vv'),
-    DartLib('Int32x4.zwzy', 'Vv'),
-    DartLib('Int32x4.zwzz', 'Vv'),
-    DartLib('Int32x4.zwzw', 'Vv'),
-    DartLib('Int32x4.zwwx', 'Vv'),
-    DartLib('Int32x4.zwwy', 'Vv'),
-    DartLib('Int32x4.zwwz', 'Vv'),
-    DartLib('Int32x4.zwww', 'Vv'),
-    DartLib('Int32x4.wxxx', 'Vv'),
-    DartLib('Int32x4.wxxy', 'Vv'),
-    DartLib('Int32x4.wxxz', 'Vv'),
-    DartLib('Int32x4.wxxw', 'Vv'),
-    DartLib('Int32x4.wxyx', 'Vv'),
-    DartLib('Int32x4.wxyy', 'Vv'),
-    DartLib('Int32x4.wxyz', 'Vv'),
-    DartLib('Int32x4.wxyw', 'Vv'),
-    DartLib('Int32x4.wxzx', 'Vv'),
-    DartLib('Int32x4.wxzy', 'Vv'),
-    DartLib('Int32x4.wxzz', 'Vv'),
-    DartLib('Int32x4.wxzw', 'Vv'),
-    DartLib('Int32x4.wxwx', 'Vv'),
-    DartLib('Int32x4.wxwy', 'Vv'),
-    DartLib('Int32x4.wxwz', 'Vv'),
-    DartLib('Int32x4.wxww', 'Vv'),
-    DartLib('Int32x4.wyxx', 'Vv'),
-    DartLib('Int32x4.wyxy', 'Vv'),
-    DartLib('Int32x4.wyxz', 'Vv'),
-    DartLib('Int32x4.wyxw', 'Vv'),
-    DartLib('Int32x4.wyyx', 'Vv'),
-    DartLib('Int32x4.wyyy', 'Vv'),
-    DartLib('Int32x4.wyyz', 'Vv'),
-    DartLib('Int32x4.wyyw', 'Vv'),
-    DartLib('Int32x4.wyzx', 'Vv'),
-    DartLib('Int32x4.wyzy', 'Vv'),
-    DartLib('Int32x4.wyzz', 'Vv'),
-    DartLib('Int32x4.wyzw', 'Vv'),
-    DartLib('Int32x4.wywx', 'Vv'),
-    DartLib('Int32x4.wywy', 'Vv'),
-    DartLib('Int32x4.wywz', 'Vv'),
-    DartLib('Int32x4.wyww', 'Vv'),
-    DartLib('Int32x4.wzxx', 'Vv'),
-    DartLib('Int32x4.wzxy', 'Vv'),
-    DartLib('Int32x4.wzxz', 'Vv'),
-    DartLib('Int32x4.wzxw', 'Vv'),
-    DartLib('Int32x4.wzyx', 'Vv'),
-    DartLib('Int32x4.wzyy', 'Vv'),
-    DartLib('Int32x4.wzyz', 'Vv'),
-    DartLib('Int32x4.wzyw', 'Vv'),
-    DartLib('Int32x4.wzzx', 'Vv'),
-    DartLib('Int32x4.wzzy', 'Vv'),
-    DartLib('Int32x4.wzzz', 'Vv'),
-    DartLib('Int32x4.wzzw', 'Vv'),
-    DartLib('Int32x4.wzwx', 'Vv'),
-    DartLib('Int32x4.wzwy', 'Vv'),
-    DartLib('Int32x4.wzwz', 'Vv'),
-    DartLib('Int32x4.wzww', 'Vv'),
-    DartLib('Int32x4.wwxx', 'Vv'),
-    DartLib('Int32x4.wwxy', 'Vv'),
-    DartLib('Int32x4.wwxz', 'Vv'),
-    DartLib('Int32x4.wwxw', 'Vv'),
-    DartLib('Int32x4.wwyx', 'Vv'),
-    DartLib('Int32x4.wwyy', 'Vv'),
-    DartLib('Int32x4.wwyz', 'Vv'),
-    DartLib('Int32x4.wwyw', 'Vv'),
-    DartLib('Int32x4.wwzx', 'Vv'),
-    DartLib('Int32x4.wwzy', 'Vv'),
-    DartLib('Int32x4.wwzz', 'Vv'),
-    DartLib('Int32x4.wwzw', 'Vv'),
+    DartLib('Float32x4.wwxw', 'Vv'),
+    DartLib('Float32x4.wwxx', 'Vv'),
+    DartLib('Float32x4.wwxy', 'Vv'),
+    DartLib('Float32x4.wwxz', 'Vv'),
+    DartLib('Float32x4.wwyw', 'Vv'),
+    DartLib('Float32x4.wwyx', 'Vv'),
+    DartLib('Float32x4.wwyy', 'Vv'),
+    DartLib('Float32x4.wwyz', 'Vv'),
+    DartLib('Float32x4.wwzw', 'Vv'),
+    DartLib('Float32x4.wwzx', 'Vv'),
+    DartLib('Float32x4.wwzy', 'Vv'),
+    DartLib('Float32x4.wwzz', 'Vv'),
+    DartLib('Float32x4.wxww', 'Vv'),
+    DartLib('Float32x4.wxwx', 'Vv'),
+    DartLib('Float32x4.wxwy', 'Vv'),
+    DartLib('Float32x4.wxwz', 'Vv'),
+    DartLib('Float32x4.wxxw', 'Vv'),
+    DartLib('Float32x4.wxxx', 'Vv'),
+    DartLib('Float32x4.wxxy', 'Vv'),
+    DartLib('Float32x4.wxxz', 'Vv'),
+    DartLib('Float32x4.wxyw', 'Vv'),
+    DartLib('Float32x4.wxyx', 'Vv'),
+    DartLib('Float32x4.wxyy', 'Vv'),
+    DartLib('Float32x4.wxyz', 'Vv'),
+    DartLib('Float32x4.wxzw', 'Vv'),
+    DartLib('Float32x4.wxzx', 'Vv'),
+    DartLib('Float32x4.wxzy', 'Vv'),
+    DartLib('Float32x4.wxzz', 'Vv'),
+    DartLib('Float32x4.wyww', 'Vv'),
+    DartLib('Float32x4.wywx', 'Vv'),
+    DartLib('Float32x4.wywy', 'Vv'),
+    DartLib('Float32x4.wywz', 'Vv'),
+    DartLib('Float32x4.wyxw', 'Vv'),
+    DartLib('Float32x4.wyxx', 'Vv'),
+    DartLib('Float32x4.wyxy', 'Vv'),
+    DartLib('Float32x4.wyxz', 'Vv'),
+    DartLib('Float32x4.wyyw', 'Vv'),
+    DartLib('Float32x4.wyyx', 'Vv'),
+    DartLib('Float32x4.wyyy', 'Vv'),
+    DartLib('Float32x4.wyyz', 'Vv'),
+    DartLib('Float32x4.wyzw', 'Vv'),
+    DartLib('Float32x4.wyzx', 'Vv'),
+    DartLib('Float32x4.wyzy', 'Vv'),
+    DartLib('Float32x4.wyzz', 'Vv'),
+    DartLib('Float32x4.wzww', 'Vv'),
+    DartLib('Float32x4.wzwx', 'Vv'),
+    DartLib('Float32x4.wzwy', 'Vv'),
+    DartLib('Float32x4.wzwz', 'Vv'),
+    DartLib('Float32x4.wzxw', 'Vv'),
+    DartLib('Float32x4.wzxx', 'Vv'),
+    DartLib('Float32x4.wzxy', 'Vv'),
+    DartLib('Float32x4.wzxz', 'Vv'),
+    DartLib('Float32x4.wzyw', 'Vv'),
+    DartLib('Float32x4.wzyx', 'Vv'),
+    DartLib('Float32x4.wzyy', 'Vv'),
+    DartLib('Float32x4.wzyz', 'Vv'),
+    DartLib('Float32x4.wzzw', 'Vv'),
+    DartLib('Float32x4.wzzx', 'Vv'),
+    DartLib('Float32x4.wzzy', 'Vv'),
+    DartLib('Float32x4.wzzz', 'Vv'),
+    DartLib('Float32x4.xwww', 'Vv'),
+    DartLib('Float32x4.xwwx', 'Vv'),
+    DartLib('Float32x4.xwwy', 'Vv'),
+    DartLib('Float32x4.xwwz', 'Vv'),
+    DartLib('Float32x4.xwxw', 'Vv'),
+    DartLib('Float32x4.xwxx', 'Vv'),
+    DartLib('Float32x4.xwxy', 'Vv'),
+    DartLib('Float32x4.xwxz', 'Vv'),
+    DartLib('Float32x4.xwyw', 'Vv'),
+    DartLib('Float32x4.xwyx', 'Vv'),
+    DartLib('Float32x4.xwyy', 'Vv'),
+    DartLib('Float32x4.xwyz', 'Vv'),
+    DartLib('Float32x4.xwzw', 'Vv'),
+    DartLib('Float32x4.xwzx', 'Vv'),
+    DartLib('Float32x4.xwzy', 'Vv'),
+    DartLib('Float32x4.xwzz', 'Vv'),
+    DartLib('Float32x4.xxww', 'Vv'),
+    DartLib('Float32x4.xxwx', 'Vv'),
+    DartLib('Float32x4.xxwy', 'Vv'),
+    DartLib('Float32x4.xxwz', 'Vv'),
+    DartLib('Float32x4.xxxw', 'Vv'),
+    DartLib('Float32x4.xxxx', 'Vv'),
+    DartLib('Float32x4.xxxy', 'Vv'),
+    DartLib('Float32x4.xxxz', 'Vv'),
+    DartLib('Float32x4.xxyw', 'Vv'),
+    DartLib('Float32x4.xxyx', 'Vv'),
+    DartLib('Float32x4.xxyy', 'Vv'),
+    DartLib('Float32x4.xxyz', 'Vv'),
+    DartLib('Float32x4.xxzw', 'Vv'),
+    DartLib('Float32x4.xxzx', 'Vv'),
+    DartLib('Float32x4.xxzy', 'Vv'),
+    DartLib('Float32x4.xxzz', 'Vv'),
+    DartLib('Float32x4.xyww', 'Vv'),
+    DartLib('Float32x4.xywx', 'Vv'),
+    DartLib('Float32x4.xywy', 'Vv'),
+    DartLib('Float32x4.xywz', 'Vv'),
+    DartLib('Float32x4.xyxw', 'Vv'),
+    DartLib('Float32x4.xyxx', 'Vv'),
+    DartLib('Float32x4.xyxy', 'Vv'),
+    DartLib('Float32x4.xyxz', 'Vv'),
+    DartLib('Float32x4.xyyw', 'Vv'),
+    DartLib('Float32x4.xyyx', 'Vv'),
+    DartLib('Float32x4.xyyy', 'Vv'),
+    DartLib('Float32x4.xyyz', 'Vv'),
+    DartLib('Float32x4.xyzw', 'Vv'),
+    DartLib('Float32x4.xyzx', 'Vv'),
+    DartLib('Float32x4.xyzy', 'Vv'),
+    DartLib('Float32x4.xyzz', 'Vv'),
+    DartLib('Float32x4.xzww', 'Vv'),
+    DartLib('Float32x4.xzwx', 'Vv'),
+    DartLib('Float32x4.xzwy', 'Vv'),
+    DartLib('Float32x4.xzwz', 'Vv'),
+    DartLib('Float32x4.xzxw', 'Vv'),
+    DartLib('Float32x4.xzxx', 'Vv'),
+    DartLib('Float32x4.xzxy', 'Vv'),
+    DartLib('Float32x4.xzxz', 'Vv'),
+    DartLib('Float32x4.xzyw', 'Vv'),
+    DartLib('Float32x4.xzyx', 'Vv'),
+    DartLib('Float32x4.xzyy', 'Vv'),
+    DartLib('Float32x4.xzyz', 'Vv'),
+    DartLib('Float32x4.xzzw', 'Vv'),
+    DartLib('Float32x4.xzzx', 'Vv'),
+    DartLib('Float32x4.xzzy', 'Vv'),
+    DartLib('Float32x4.xzzz', 'Vv'),
+    DartLib('Float32x4.ywww', 'Vv'),
+    DartLib('Float32x4.ywwx', 'Vv'),
+    DartLib('Float32x4.ywwy', 'Vv'),
+    DartLib('Float32x4.ywwz', 'Vv'),
+    DartLib('Float32x4.ywxw', 'Vv'),
+    DartLib('Float32x4.ywxx', 'Vv'),
+    DartLib('Float32x4.ywxy', 'Vv'),
+    DartLib('Float32x4.ywxz', 'Vv'),
+    DartLib('Float32x4.ywyw', 'Vv'),
+    DartLib('Float32x4.ywyx', 'Vv'),
+    DartLib('Float32x4.ywyy', 'Vv'),
+    DartLib('Float32x4.ywyz', 'Vv'),
+    DartLib('Float32x4.ywzw', 'Vv'),
+    DartLib('Float32x4.ywzx', 'Vv'),
+    DartLib('Float32x4.ywzy', 'Vv'),
+    DartLib('Float32x4.ywzz', 'Vv'),
+    DartLib('Float32x4.yxww', 'Vv'),
+    DartLib('Float32x4.yxwx', 'Vv'),
+    DartLib('Float32x4.yxwy', 'Vv'),
+    DartLib('Float32x4.yxwz', 'Vv'),
+    DartLib('Float32x4.yxxw', 'Vv'),
+    DartLib('Float32x4.yxxx', 'Vv'),
+    DartLib('Float32x4.yxxy', 'Vv'),
+    DartLib('Float32x4.yxxz', 'Vv'),
+    DartLib('Float32x4.yxyw', 'Vv'),
+    DartLib('Float32x4.yxyx', 'Vv'),
+    DartLib('Float32x4.yxyy', 'Vv'),
+    DartLib('Float32x4.yxyz', 'Vv'),
+    DartLib('Float32x4.yxzw', 'Vv'),
+    DartLib('Float32x4.yxzx', 'Vv'),
+    DartLib('Float32x4.yxzy', 'Vv'),
+    DartLib('Float32x4.yxzz', 'Vv'),
+    DartLib('Float32x4.yyww', 'Vv'),
+    DartLib('Float32x4.yywx', 'Vv'),
+    DartLib('Float32x4.yywy', 'Vv'),
+    DartLib('Float32x4.yywz', 'Vv'),
+    DartLib('Float32x4.yyxw', 'Vv'),
+    DartLib('Float32x4.yyxx', 'Vv'),
+    DartLib('Float32x4.yyxy', 'Vv'),
+    DartLib('Float32x4.yyxz', 'Vv'),
+    DartLib('Float32x4.yyyw', 'Vv'),
+    DartLib('Float32x4.yyyx', 'Vv'),
+    DartLib('Float32x4.yyyy', 'Vv'),
+    DartLib('Float32x4.yyyz', 'Vv'),
+    DartLib('Float32x4.yyzw', 'Vv'),
+    DartLib('Float32x4.yyzx', 'Vv'),
+    DartLib('Float32x4.yyzy', 'Vv'),
+    DartLib('Float32x4.yyzz', 'Vv'),
+    DartLib('Float32x4.yzww', 'Vv'),
+    DartLib('Float32x4.yzwx', 'Vv'),
+    DartLib('Float32x4.yzwy', 'Vv'),
+    DartLib('Float32x4.yzwz', 'Vv'),
+    DartLib('Float32x4.yzxw', 'Vv'),
+    DartLib('Float32x4.yzxx', 'Vv'),
+    DartLib('Float32x4.yzxy', 'Vv'),
+    DartLib('Float32x4.yzxz', 'Vv'),
+    DartLib('Float32x4.yzyw', 'Vv'),
+    DartLib('Float32x4.yzyx', 'Vv'),
+    DartLib('Float32x4.yzyy', 'Vv'),
+    DartLib('Float32x4.yzyz', 'Vv'),
+    DartLib('Float32x4.yzzw', 'Vv'),
+    DartLib('Float32x4.yzzx', 'Vv'),
+    DartLib('Float32x4.yzzy', 'Vv'),
+    DartLib('Float32x4.yzzz', 'Vv'),
+    DartLib('Float32x4.zwww', 'Vv'),
+    DartLib('Float32x4.zwwx', 'Vv'),
+    DartLib('Float32x4.zwwy', 'Vv'),
+    DartLib('Float32x4.zwwz', 'Vv'),
+    DartLib('Float32x4.zwxw', 'Vv'),
+    DartLib('Float32x4.zwxx', 'Vv'),
+    DartLib('Float32x4.zwxy', 'Vv'),
+    DartLib('Float32x4.zwxz', 'Vv'),
+    DartLib('Float32x4.zwyw', 'Vv'),
+    DartLib('Float32x4.zwyx', 'Vv'),
+    DartLib('Float32x4.zwyy', 'Vv'),
+    DartLib('Float32x4.zwyz', 'Vv'),
+    DartLib('Float32x4.zwzw', 'Vv'),
+    DartLib('Float32x4.zwzx', 'Vv'),
+    DartLib('Float32x4.zwzy', 'Vv'),
+    DartLib('Float32x4.zwzz', 'Vv'),
+    DartLib('Float32x4.zxww', 'Vv'),
+    DartLib('Float32x4.zxwx', 'Vv'),
+    DartLib('Float32x4.zxwy', 'Vv'),
+    DartLib('Float32x4.zxwz', 'Vv'),
+    DartLib('Float32x4.zxxw', 'Vv'),
+    DartLib('Float32x4.zxxx', 'Vv'),
+    DartLib('Float32x4.zxxy', 'Vv'),
+    DartLib('Float32x4.zxxz', 'Vv'),
+    DartLib('Float32x4.zxyw', 'Vv'),
+    DartLib('Float32x4.zxyx', 'Vv'),
+    DartLib('Float32x4.zxyy', 'Vv'),
+    DartLib('Float32x4.zxyz', 'Vv'),
+    DartLib('Float32x4.zxzw', 'Vv'),
+    DartLib('Float32x4.zxzx', 'Vv'),
+    DartLib('Float32x4.zxzy', 'Vv'),
+    DartLib('Float32x4.zxzz', 'Vv'),
+    DartLib('Float32x4.zyww', 'Vv'),
+    DartLib('Float32x4.zywx', 'Vv'),
+    DartLib('Float32x4.zywy', 'Vv'),
+    DartLib('Float32x4.zywz', 'Vv'),
+    DartLib('Float32x4.zyxw', 'Vv'),
+    DartLib('Float32x4.zyxx', 'Vv'),
+    DartLib('Float32x4.zyxy', 'Vv'),
+    DartLib('Float32x4.zyxz', 'Vv'),
+    DartLib('Float32x4.zyyw', 'Vv'),
+    DartLib('Float32x4.zyyx', 'Vv'),
+    DartLib('Float32x4.zyyy', 'Vv'),
+    DartLib('Float32x4.zyyz', 'Vv'),
+    DartLib('Float32x4.zyzw', 'Vv'),
+    DartLib('Float32x4.zyzx', 'Vv'),
+    DartLib('Float32x4.zyzy', 'Vv'),
+    DartLib('Float32x4.zyzz', 'Vv'),
+    DartLib('Float32x4.zzww', 'Vv'),
+    DartLib('Float32x4.zzwx', 'Vv'),
+    DartLib('Float32x4.zzwy', 'Vv'),
+    DartLib('Float32x4.zzwz', 'Vv'),
+    DartLib('Float32x4.zzxw', 'Vv'),
+    DartLib('Float32x4.zzxx', 'Vv'),
+    DartLib('Float32x4.zzxy', 'Vv'),
+    DartLib('Float32x4.zzxz', 'Vv'),
+    DartLib('Float32x4.zzyw', 'Vv'),
+    DartLib('Float32x4.zzyx', 'Vv'),
+    DartLib('Float32x4.zzyy', 'Vv'),
+    DartLib('Float32x4.zzyz', 'Vv'),
+    DartLib('Float32x4.zzzw', 'Vv'),
+    DartLib('Float32x4.zzzx', 'Vv'),
+    DartLib('Float32x4.zzzy', 'Vv'),
+    DartLib('Float32x4.zzzz', 'Vv'),
+    DartLib('Float32x4List.bytesPerElement', 'Vv'),
+    DartLib('Float64List.bytesPerElement', 'Vv'),
+    DartLib('Float64x2List.bytesPerElement', 'Vv'),
+    DartLib('Int16List.bytesPerElement', 'Vv'),
+    DartLib('Int32List.bytesPerElement', 'Vv'),
+    DartLib('Int32x4.wwww', 'Vv'),
     DartLib('Int32x4.wwwx', 'Vv'),
     DartLib('Int32x4.wwwy', 'Vv'),
     DartLib('Int32x4.wwwz', 'Vv'),
-    DartLib('Int32x4.wwww', 'Vv'),
+    DartLib('Int32x4.wwxw', 'Vv'),
+    DartLib('Int32x4.wwxx', 'Vv'),
+    DartLib('Int32x4.wwxy', 'Vv'),
+    DartLib('Int32x4.wwxz', 'Vv'),
+    DartLib('Int32x4.wwyw', 'Vv'),
+    DartLib('Int32x4.wwyx', 'Vv'),
+    DartLib('Int32x4.wwyy', 'Vv'),
+    DartLib('Int32x4.wwyz', 'Vv'),
+    DartLib('Int32x4.wwzw', 'Vv'),
+    DartLib('Int32x4.wwzx', 'Vv'),
+    DartLib('Int32x4.wwzy', 'Vv'),
+    DartLib('Int32x4.wwzz', 'Vv'),
+    DartLib('Int32x4.wxww', 'Vv'),
+    DartLib('Int32x4.wxwx', 'Vv'),
+    DartLib('Int32x4.wxwy', 'Vv'),
+    DartLib('Int32x4.wxwz', 'Vv'),
+    DartLib('Int32x4.wxxw', 'Vv'),
+    DartLib('Int32x4.wxxx', 'Vv'),
+    DartLib('Int32x4.wxxy', 'Vv'),
+    DartLib('Int32x4.wxxz', 'Vv'),
+    DartLib('Int32x4.wxyw', 'Vv'),
+    DartLib('Int32x4.wxyx', 'Vv'),
+    DartLib('Int32x4.wxyy', 'Vv'),
+    DartLib('Int32x4.wxyz', 'Vv'),
+    DartLib('Int32x4.wxzw', 'Vv'),
+    DartLib('Int32x4.wxzx', 'Vv'),
+    DartLib('Int32x4.wxzy', 'Vv'),
+    DartLib('Int32x4.wxzz', 'Vv'),
+    DartLib('Int32x4.wyww', 'Vv'),
+    DartLib('Int32x4.wywx', 'Vv'),
+    DartLib('Int32x4.wywy', 'Vv'),
+    DartLib('Int32x4.wywz', 'Vv'),
+    DartLib('Int32x4.wyxw', 'Vv'),
+    DartLib('Int32x4.wyxx', 'Vv'),
+    DartLib('Int32x4.wyxy', 'Vv'),
+    DartLib('Int32x4.wyxz', 'Vv'),
+    DartLib('Int32x4.wyyw', 'Vv'),
+    DartLib('Int32x4.wyyx', 'Vv'),
+    DartLib('Int32x4.wyyy', 'Vv'),
+    DartLib('Int32x4.wyyz', 'Vv'),
+    DartLib('Int32x4.wyzw', 'Vv'),
+    DartLib('Int32x4.wyzx', 'Vv'),
+    DartLib('Int32x4.wyzy', 'Vv'),
+    DartLib('Int32x4.wyzz', 'Vv'),
+    DartLib('Int32x4.wzww', 'Vv'),
+    DartLib('Int32x4.wzwx', 'Vv'),
+    DartLib('Int32x4.wzwy', 'Vv'),
+    DartLib('Int32x4.wzwz', 'Vv'),
+    DartLib('Int32x4.wzxw', 'Vv'),
+    DartLib('Int32x4.wzxx', 'Vv'),
+    DartLib('Int32x4.wzxy', 'Vv'),
+    DartLib('Int32x4.wzxz', 'Vv'),
+    DartLib('Int32x4.wzyw', 'Vv'),
+    DartLib('Int32x4.wzyx', 'Vv'),
+    DartLib('Int32x4.wzyy', 'Vv'),
+    DartLib('Int32x4.wzyz', 'Vv'),
+    DartLib('Int32x4.wzzw', 'Vv'),
+    DartLib('Int32x4.wzzx', 'Vv'),
+    DartLib('Int32x4.wzzy', 'Vv'),
+    DartLib('Int32x4.wzzz', 'Vv'),
+    DartLib('Int32x4.xwww', 'Vv'),
+    DartLib('Int32x4.xwwx', 'Vv'),
+    DartLib('Int32x4.xwwy', 'Vv'),
+    DartLib('Int32x4.xwwz', 'Vv'),
+    DartLib('Int32x4.xwxw', 'Vv'),
+    DartLib('Int32x4.xwxx', 'Vv'),
+    DartLib('Int32x4.xwxy', 'Vv'),
+    DartLib('Int32x4.xwxz', 'Vv'),
+    DartLib('Int32x4.xwyw', 'Vv'),
+    DartLib('Int32x4.xwyx', 'Vv'),
+    DartLib('Int32x4.xwyy', 'Vv'),
+    DartLib('Int32x4.xwyz', 'Vv'),
+    DartLib('Int32x4.xwzw', 'Vv'),
+    DartLib('Int32x4.xwzx', 'Vv'),
+    DartLib('Int32x4.xwzy', 'Vv'),
+    DartLib('Int32x4.xwzz', 'Vv'),
+    DartLib('Int32x4.xxww', 'Vv'),
+    DartLib('Int32x4.xxwx', 'Vv'),
+    DartLib('Int32x4.xxwy', 'Vv'),
+    DartLib('Int32x4.xxwz', 'Vv'),
+    DartLib('Int32x4.xxxw', 'Vv'),
+    DartLib('Int32x4.xxxx', 'Vv'),
+    DartLib('Int32x4.xxxy', 'Vv'),
+    DartLib('Int32x4.xxxz', 'Vv'),
+    DartLib('Int32x4.xxyw', 'Vv'),
+    DartLib('Int32x4.xxyx', 'Vv'),
+    DartLib('Int32x4.xxyy', 'Vv'),
+    DartLib('Int32x4.xxyz', 'Vv'),
+    DartLib('Int32x4.xxzw', 'Vv'),
+    DartLib('Int32x4.xxzx', 'Vv'),
+    DartLib('Int32x4.xxzy', 'Vv'),
+    DartLib('Int32x4.xxzz', 'Vv'),
+    DartLib('Int32x4.xyww', 'Vv'),
+    DartLib('Int32x4.xywx', 'Vv'),
+    DartLib('Int32x4.xywy', 'Vv'),
+    DartLib('Int32x4.xywz', 'Vv'),
+    DartLib('Int32x4.xyxw', 'Vv'),
+    DartLib('Int32x4.xyxx', 'Vv'),
+    DartLib('Int32x4.xyxy', 'Vv'),
+    DartLib('Int32x4.xyxz', 'Vv'),
+    DartLib('Int32x4.xyyw', 'Vv'),
+    DartLib('Int32x4.xyyx', 'Vv'),
+    DartLib('Int32x4.xyyy', 'Vv'),
+    DartLib('Int32x4.xyyz', 'Vv'),
+    DartLib('Int32x4.xyzw', 'Vv'),
+    DartLib('Int32x4.xyzx', 'Vv'),
+    DartLib('Int32x4.xyzy', 'Vv'),
+    DartLib('Int32x4.xyzz', 'Vv'),
+    DartLib('Int32x4.xzww', 'Vv'),
+    DartLib('Int32x4.xzwx', 'Vv'),
+    DartLib('Int32x4.xzwy', 'Vv'),
+    DartLib('Int32x4.xzwz', 'Vv'),
+    DartLib('Int32x4.xzxw', 'Vv'),
+    DartLib('Int32x4.xzxx', 'Vv'),
+    DartLib('Int32x4.xzxy', 'Vv'),
+    DartLib('Int32x4.xzxz', 'Vv'),
+    DartLib('Int32x4.xzyw', 'Vv'),
+    DartLib('Int32x4.xzyx', 'Vv'),
+    DartLib('Int32x4.xzyy', 'Vv'),
+    DartLib('Int32x4.xzyz', 'Vv'),
+    DartLib('Int32x4.xzzw', 'Vv'),
+    DartLib('Int32x4.xzzx', 'Vv'),
+    DartLib('Int32x4.xzzy', 'Vv'),
+    DartLib('Int32x4.xzzz', 'Vv'),
+    DartLib('Int32x4.ywww', 'Vv'),
+    DartLib('Int32x4.ywwx', 'Vv'),
+    DartLib('Int32x4.ywwy', 'Vv'),
+    DartLib('Int32x4.ywwz', 'Vv'),
+    DartLib('Int32x4.ywxw', 'Vv'),
+    DartLib('Int32x4.ywxx', 'Vv'),
+    DartLib('Int32x4.ywxy', 'Vv'),
+    DartLib('Int32x4.ywxz', 'Vv'),
+    DartLib('Int32x4.ywyw', 'Vv'),
+    DartLib('Int32x4.ywyx', 'Vv'),
+    DartLib('Int32x4.ywyy', 'Vv'),
+    DartLib('Int32x4.ywyz', 'Vv'),
+    DartLib('Int32x4.ywzw', 'Vv'),
+    DartLib('Int32x4.ywzx', 'Vv'),
+    DartLib('Int32x4.ywzy', 'Vv'),
+    DartLib('Int32x4.ywzz', 'Vv'),
+    DartLib('Int32x4.yxww', 'Vv'),
+    DartLib('Int32x4.yxwx', 'Vv'),
+    DartLib('Int32x4.yxwy', 'Vv'),
+    DartLib('Int32x4.yxwz', 'Vv'),
+    DartLib('Int32x4.yxxw', 'Vv'),
+    DartLib('Int32x4.yxxx', 'Vv'),
+    DartLib('Int32x4.yxxy', 'Vv'),
+    DartLib('Int32x4.yxxz', 'Vv'),
+    DartLib('Int32x4.yxyw', 'Vv'),
+    DartLib('Int32x4.yxyx', 'Vv'),
+    DartLib('Int32x4.yxyy', 'Vv'),
+    DartLib('Int32x4.yxyz', 'Vv'),
+    DartLib('Int32x4.yxzw', 'Vv'),
+    DartLib('Int32x4.yxzx', 'Vv'),
+    DartLib('Int32x4.yxzy', 'Vv'),
+    DartLib('Int32x4.yxzz', 'Vv'),
+    DartLib('Int32x4.yyww', 'Vv'),
+    DartLib('Int32x4.yywx', 'Vv'),
+    DartLib('Int32x4.yywy', 'Vv'),
+    DartLib('Int32x4.yywz', 'Vv'),
+    DartLib('Int32x4.yyxw', 'Vv'),
+    DartLib('Int32x4.yyxx', 'Vv'),
+    DartLib('Int32x4.yyxy', 'Vv'),
+    DartLib('Int32x4.yyxz', 'Vv'),
+    DartLib('Int32x4.yyyw', 'Vv'),
+    DartLib('Int32x4.yyyx', 'Vv'),
+    DartLib('Int32x4.yyyy', 'Vv'),
+    DartLib('Int32x4.yyyz', 'Vv'),
+    DartLib('Int32x4.yyzw', 'Vv'),
+    DartLib('Int32x4.yyzx', 'Vv'),
+    DartLib('Int32x4.yyzy', 'Vv'),
+    DartLib('Int32x4.yyzz', 'Vv'),
+    DartLib('Int32x4.yzww', 'Vv'),
+    DartLib('Int32x4.yzwx', 'Vv'),
+    DartLib('Int32x4.yzwy', 'Vv'),
+    DartLib('Int32x4.yzwz', 'Vv'),
+    DartLib('Int32x4.yzxw', 'Vv'),
+    DartLib('Int32x4.yzxx', 'Vv'),
+    DartLib('Int32x4.yzxy', 'Vv'),
+    DartLib('Int32x4.yzxz', 'Vv'),
+    DartLib('Int32x4.yzyw', 'Vv'),
+    DartLib('Int32x4.yzyx', 'Vv'),
+    DartLib('Int32x4.yzyy', 'Vv'),
+    DartLib('Int32x4.yzyz', 'Vv'),
+    DartLib('Int32x4.yzzw', 'Vv'),
+    DartLib('Int32x4.yzzx', 'Vv'),
+    DartLib('Int32x4.yzzy', 'Vv'),
+    DartLib('Int32x4.yzzz', 'Vv'),
+    DartLib('Int32x4.zwww', 'Vv'),
+    DartLib('Int32x4.zwwx', 'Vv'),
+    DartLib('Int32x4.zwwy', 'Vv'),
+    DartLib('Int32x4.zwwz', 'Vv'),
+    DartLib('Int32x4.zwxw', 'Vv'),
+    DartLib('Int32x4.zwxx', 'Vv'),
+    DartLib('Int32x4.zwxy', 'Vv'),
+    DartLib('Int32x4.zwxz', 'Vv'),
+    DartLib('Int32x4.zwyw', 'Vv'),
+    DartLib('Int32x4.zwyx', 'Vv'),
+    DartLib('Int32x4.zwyy', 'Vv'),
+    DartLib('Int32x4.zwyz', 'Vv'),
+    DartLib('Int32x4.zwzw', 'Vv'),
+    DartLib('Int32x4.zwzx', 'Vv'),
+    DartLib('Int32x4.zwzy', 'Vv'),
+    DartLib('Int32x4.zwzz', 'Vv'),
+    DartLib('Int32x4.zxww', 'Vv'),
+    DartLib('Int32x4.zxwx', 'Vv'),
+    DartLib('Int32x4.zxwy', 'Vv'),
+    DartLib('Int32x4.zxwz', 'Vv'),
+    DartLib('Int32x4.zxxw', 'Vv'),
+    DartLib('Int32x4.zxxx', 'Vv'),
+    DartLib('Int32x4.zxxy', 'Vv'),
+    DartLib('Int32x4.zxxz', 'Vv'),
+    DartLib('Int32x4.zxyw', 'Vv'),
+    DartLib('Int32x4.zxyx', 'Vv'),
+    DartLib('Int32x4.zxyy', 'Vv'),
+    DartLib('Int32x4.zxyz', 'Vv'),
+    DartLib('Int32x4.zxzw', 'Vv'),
+    DartLib('Int32x4.zxzx', 'Vv'),
+    DartLib('Int32x4.zxzy', 'Vv'),
+    DartLib('Int32x4.zxzz', 'Vv'),
+    DartLib('Int32x4.zyww', 'Vv'),
+    DartLib('Int32x4.zywx', 'Vv'),
+    DartLib('Int32x4.zywy', 'Vv'),
+    DartLib('Int32x4.zywz', 'Vv'),
+    DartLib('Int32x4.zyxw', 'Vv'),
+    DartLib('Int32x4.zyxx', 'Vv'),
+    DartLib('Int32x4.zyxy', 'Vv'),
+    DartLib('Int32x4.zyxz', 'Vv'),
+    DartLib('Int32x4.zyyw', 'Vv'),
+    DartLib('Int32x4.zyyx', 'Vv'),
+    DartLib('Int32x4.zyyy', 'Vv'),
+    DartLib('Int32x4.zyyz', 'Vv'),
+    DartLib('Int32x4.zyzw', 'Vv'),
+    DartLib('Int32x4.zyzx', 'Vv'),
+    DartLib('Int32x4.zyzy', 'Vv'),
+    DartLib('Int32x4.zyzz', 'Vv'),
+    DartLib('Int32x4.zzww', 'Vv'),
+    DartLib('Int32x4.zzwx', 'Vv'),
+    DartLib('Int32x4.zzwy', 'Vv'),
+    DartLib('Int32x4.zzwz', 'Vv'),
+    DartLib('Int32x4.zzxw', 'Vv'),
+    DartLib('Int32x4.zzxx', 'Vv'),
+    DartLib('Int32x4.zzxy', 'Vv'),
+    DartLib('Int32x4.zzxz', 'Vv'),
+    DartLib('Int32x4.zzyw', 'Vv'),
+    DartLib('Int32x4.zzyx', 'Vv'),
+    DartLib('Int32x4.zzyy', 'Vv'),
+    DartLib('Int32x4.zzyz', 'Vv'),
+    DartLib('Int32x4.zzzw', 'Vv'),
+    DartLib('Int32x4.zzzx', 'Vv'),
+    DartLib('Int32x4.zzzy', 'Vv'),
+    DartLib('Int32x4.zzzz', 'Vv'),
+    DartLib('Int32x4List.bytesPerElement', 'Vv'),
+    DartLib('Int64List.bytesPerElement', 'Vv'),
+    DartLib('Int8List.bytesPerElement', 'Vv'),
+    DartLib('Isolate.beforeNextEvent', 'Vv'),
+    DartLib('Isolate.immediate', 'Vv'),
+    DartLib('JsonUtf8Encoder.DEFAULT_BUFFER_SIZE', 'Vv'),
+    DartLib('OSError.noErrorCode', 'Vv'),
+    DartLib('RangeError.checkValidRange', 'VIIISSS'),
+    DartLib('RawSocketOption.IPv4MulticastInterface', 'Vv'),
+    DartLib('RawSocketOption.IPv6MulticastInterface', 'Vv'),
+    DartLib('RawSocketOption.levelIPv4', 'Vv'),
+    DartLib('RawSocketOption.levelIPv6', 'Vv'),
+    DartLib('RawSocketOption.levelSocket', 'Vv'),
+    DartLib('RawSocketOption.levelTcp', 'Vv'),
+    DartLib('RawSocketOption.levelUdp', 'Vv'),
+    DartLib('Uint16List.bytesPerElement', 'Vv'),
+    DartLib('Uint32List.bytesPerElement', 'Vv'),
+    DartLib('Uint64List.bytesPerElement', 'Vv'),
+    DartLib('Uint8ClampedList.bytesPerElement', 'Vv'),
+    DartLib('Uint8List.bytesPerElement', 'Vv'),
+    DartLib('ZLibOption.DEFAULT_LEVEL', 'Vv'),
+    DartLib('ZLibOption.DEFAULT_MEM_LEVEL', 'Vv'),
+    DartLib('ZLibOption.DEFAULT_WINDOW_BITS', 'Vv'),
+    DartLib('ZLibOption.MAX_LEVEL', 'Vv'),
+    DartLib('ZLibOption.MAX_MEM_LEVEL', 'Vv'),
+    DartLib('ZLibOption.MAX_WINDOW_BITS', 'Vv'),
+    DartLib('ZLibOption.MIN_LEVEL', 'Vv'),
+    DartLib('ZLibOption.MIN_MEM_LEVEL', 'Vv'),
+    DartLib('ZLibOption.MIN_WINDOW_BITS', 'Vv'),
+    DartLib('ZLibOption.STRATEGY_DEFAULT', 'Vv'),
+    DartLib('ZLibOption.STRATEGY_FILTERED', 'Vv'),
+    DartLib('ZLibOption.STRATEGY_FIXED', 'Vv'),
+    DartLib('ZLibOption.STRATEGY_HUFFMAN_ONLY', 'Vv'),
+    DartLib('ZLibOption.STRATEGY_RLE', 'Vv'),
+    DartLib('ZLibOption.defaultLevel', 'Vv'),
+    DartLib('ZLibOption.defaultMemLevel', 'Vv'),
+    DartLib('ZLibOption.defaultWindowBits', 'Vv'),
+    DartLib('ZLibOption.maxLevel', 'Vv'),
+    DartLib('ZLibOption.maxMemLevel', 'Vv'),
+    DartLib('ZLibOption.maxWindowBits', 'Vv'),
+    DartLib('ZLibOption.minLevel', 'Vv'),
+    DartLib('ZLibOption.minMemLevel', 'Vv'),
+    DartLib('ZLibOption.minWindowBits', 'Vv'),
+    DartLib('ZLibOption.strategyDefault', 'Vv'),
+    DartLib('ZLibOption.strategyFiltered', 'Vv'),
+    DartLib('ZLibOption.strategyFixed', 'Vv'),
+    DartLib('ZLibOption.strategyHuffmanOnly', 'Vv'),
+    DartLib('ZLibOption.strategyRle', 'Vv'),
+    DartLib('abs', 'IV'),
+    DartLib('bitLength', 'Iv'),
+    DartLib('ceil', 'DV'),
+    DartLib('ceil', 'DV'),
+    DartLib('ceil', 'IV'),
+    DartLib('codeUnitAt', 'SI'),
+    DartLib('compareTo', 'DD'),
+    DartLib('compareTo', 'SS'),
+    DartLib('floor', 'IV'),
+    DartLib('floor', 'DV'),
+    DartLib('floor', 'DV'),
+    DartLib('gcd', 'II'),
+    DartLib('indexOf', 'LII'),
+    DartLib('int.fromEnvironment', 'VS'),
+    DartLib('int.parse', 'VS'),
+    DartLib('int.tryParse', 'VS'),
+    DartLib('lastIndexOf', 'LII'),
+    DartLib('length', 'Mv'),
+    DartLib('length', 'Lv'),
+    DartLib('length', 'Sv'),
+    DartLib('modInverse', 'II'),
+    DartLib('modPow', 'III'),
+    DartLib('removeAt', 'LI'),
+    DartLib('removeLast', 'LV'),
+    DartLib('round', 'DV'),
+    DartLib('round', 'IV'),
+    DartLib('round', 'DV'),
+    DartLib('sign', 'Iv'),
+    DartLib('toInt', 'DV'),
+    DartLib('toSigned', 'II'),
+    DartLib('toUnsigned', 'II'),
+    DartLib('truncate', 'DV'),
+    DartLib('truncate', 'IV'),
+    DartLib('truncate', 'DV'),
+    DartLib('unicodeBomCharacterRune', 'Vv'),
+    DartLib('unicodeReplacementCharacterRune', 'Vv'),
   ];
   static const doubleLibs = [
-    DartLib('remainder', 'DD'),
     DartLib('abs', 'DV'),
-    DartLib('roundToDouble', 'DV'),
-    DartLib('floorToDouble', 'DV'),
-    DartLib('ceilToDouble', 'DV'),
-    DartLib('truncateToDouble', 'DV'),
-    DartLib('double.tryParse', 'VS'),
-    DartLib('sign', 'Dv'),
-    DartLib('double.nan', 'Vv'),
-    DartLib('double.infinity', 'Vv'),
-    DartLib('double.negativeInfinity', 'Vv'),
-    DartLib('double.minPositive', 'Vv'),
-    DartLib('double.maxFinite', 'Vv'),
-    DartLib('roundToDouble', 'IV'),
-    DartLib('floorToDouble', 'IV'),
-    DartLib('ceilToDouble', 'IV'),
-    DartLib('truncateToDouble', 'IV'),
-    DartLib('remainder', 'DD'),
     DartLib('abs', 'DV'),
-    DartLib('roundToDouble', 'DV'),
-    DartLib('floorToDouble', 'DV'),
-    DartLib('ceilToDouble', 'DV'),
-    DartLib('truncateToDouble', 'DV'),
-    DartLib('clamp', 'DDD'),
-    DartLib('toDouble', 'DV'),
-    DartLib('num.tryParse', 'VS'),
-    DartLib('sign', 'Dv'),
-    DartLib('e', 'Vv'),
-    DartLib('ln10', 'Vv'),
-    DartLib('ln2', 'Vv'),
-    DartLib('log2e', 'Vv'),
-    DartLib('log10e', 'Vv'),
-    DartLib('pi', 'Vv'),
-    DartLib('sqrt1_2', 'Vv'),
-    DartLib('sqrt2', 'Vv'),
-    DartLib('atan2', 'VDD'),
-    DartLib('pow', 'VDD'),
-    DartLib('sin', 'VD'),
-    DartLib('cos', 'VD'),
-    DartLib('tan', 'VD'),
     DartLib('acos', 'VD'),
     DartLib('asin', 'VD'),
     DartLib('atan', 'VD'),
-    DartLib('sqrt', 'VD'),
+    DartLib('atan2', 'VDD'),
+    DartLib('ceilToDouble', 'DV'),
+    DartLib('ceilToDouble', 'DV'),
+    DartLib('ceilToDouble', 'IV'),
+    DartLib('clamp', 'DDD'),
+    DartLib('cos', 'VD'),
+    DartLib('double.infinity', 'Vv'),
+    DartLib('double.maxFinite', 'Vv'),
+    DartLib('double.minPositive', 'Vv'),
+    DartLib('double.nan', 'Vv'),
+    DartLib('double.negativeInfinity', 'Vv'),
+    DartLib('double.tryParse', 'VS'),
+    DartLib('e', 'Vv'),
     DartLib('exp', 'VD'),
+    DartLib('floorToDouble', 'DV'),
+    DartLib('floorToDouble', 'IV'),
+    DartLib('floorToDouble', 'DV'),
+    DartLib('ln10', 'Vv'),
+    DartLib('ln2', 'Vv'),
     DartLib('log', 'VD'),
+    DartLib('log10e', 'Vv'),
+    DartLib('log2e', 'Vv'),
+    DartLib('num.tryParse', 'VS'),
+    DartLib('pi', 'Vv'),
+    DartLib('pow', 'VDD'),
+    DartLib('remainder', 'DD'),
+    DartLib('remainder', 'DD'),
+    DartLib('roundToDouble', 'IV'),
+    DartLib('roundToDouble', 'DV'),
+    DartLib('roundToDouble', 'DV'),
+    DartLib('sign', 'Dv'),
+    DartLib('sign', 'Dv'),
+    DartLib('sin', 'VD'),
+    DartLib('sqrt', 'VD'),
+    DartLib('sqrt1_2', 'Vv'),
+    DartLib('sqrt2', 'Vv'),
+    DartLib('tan', 'VD'),
+    DartLib('toDouble', 'DV'),
+    DartLib('truncateToDouble', 'IV'),
+    DartLib('truncateToDouble', 'DV'),
+    DartLib('truncateToDouble', 'DV'),
   ];
   static const stringLibs = [
     DartLib('ListBase.listToString', 'VL'),
     DartLib('MapBase.mapToString', 'VM'),
-    DartLib('SetBase.setToString', 'VX'),
-    DartLib('base64Encode', 'VL'),
-    DartLib('base64UrlEncode', 'VL'),
-    DartLib('toString', 'BV'),
-    DartLib('toString', 'DV'),
-    DartLib('toString', 'IV'),
-    DartLib('toRadixString', 'II'),
-    DartLib('toStringAsFixed', 'DI'),
-    DartLib('toStringAsExponential', 'DI'),
-    DartLib('toStringAsPrecision', 'DI'),
-    DartLib('toString', 'DV'),
     DartLib('RegExp.escape', 'VS'),
+    DartLib('SetBase.setToString', 'VX'),
     DartLib('String.fromCharCode', 'VI'),
     DartLib('String.fromEnvironment', 'VS'),
-    DartLib('substring', 'SII'),
-    DartLib('trim', 'SV'),
-    DartLib('trimLeft', 'SV'),
-    DartLib('trimRight', 'SV'),
+    DartLib('Uri.decodeComponent', 'VS'),
+    DartLib('Uri.decodeFull', 'VS'),
+    DartLib('Uri.decodeQueryComponent', 'VS'),
+    DartLib('Uri.encodeComponent', 'VS'),
+    DartLib('Uri.encodeFull', 'VS'),
+    DartLib('Uri.encodeQueryComponent', 'VS'),
+    DartLib('base64Encode', 'VL'),
+    DartLib('base64UrlEncode', 'VL'),
     DartLib('padLeft', 'Sis'),
     DartLib('padRight', 'Sis'),
     DartLib('replaceRange', 'SIIS'),
+    DartLib('substring', 'SII'),
     DartLib('toLowerCase', 'SV'),
+    DartLib('toRadixString', 'II'),
+    DartLib('toString', 'BV'),
+    DartLib('toString', 'DV'),
+    DartLib('toString', 'IV'),
+    DartLib('toString', 'DV'),
+    DartLib('toStringAsExponential', 'DI'),
+    DartLib('toStringAsFixed', 'DI'),
+    DartLib('toStringAsPrecision', 'DI'),
     DartLib('toUpperCase', 'SV'),
-    DartLib('Uri.encodeComponent', 'VS'),
-    DartLib('Uri.encodeQueryComponent', 'VS'),
-    DartLib('Uri.decodeComponent', 'VS'),
-    DartLib('Uri.decodeQueryComponent', 'VS'),
-    DartLib('Uri.encodeFull', 'VS'),
-    DartLib('Uri.decodeFull', 'VS'),
+    DartLib('trim', 'SV'),
+    DartLib('trimLeft', 'SV'),
+    DartLib('trimRight', 'SV'),
   ];
   static const listLibs = [
     DartLib('List.filled', 'ViI'),
-    DartLib('sublist', 'LII'),
-    DartLib('codeUnits', 'Sv'),
     DartLib('Uri.parseIPv4Address', 'VS'),
     DartLib('Uri.parseIPv6Address', 'VSII'),
+    DartLib('codeUnits', 'Sv'),
+    DartLib('sublist', 'LII'),
   ];
   static const setLibs = [
     DartLib('Set.identity', 'VV'),
-    DartLib('intersection', 'XX'),
-    DartLib('union', 'XX'),
     DartLib('difference', 'XX'),
+    DartLib('intersection', 'XX'),
     DartLib('toSet', 'XV'),
+    DartLib('union', 'XX'),
   ];
   static const mapLibs = [
     DartLib('Map.from', 'VM'),
+    DartLib('Map.identity', 'VV'),
     DartLib('Map.of', 'VM'),
     DartLib('Map.unmodifiable', 'VM'),
-    DartLib('Map.identity', 'VV'),
   ];
 }
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index dc61138..1510b3f 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -345,12 +345,13 @@
     fp = samePrecision(mode1, mode2);
     // Occasionally test FFI.
     ffi = ffiCapable(mode1, mode2) && (rand.nextInt(5) == 0);
+    flatTp = !nestedTypesAllowed(mode1, mode2) || (rand.nextInt(5) == 0);
     runner1 =
         TestRunner.getTestRunner(mode1, top, tmpDir.path, env, fileName, rand);
     runner2 =
         TestRunner.getTestRunner(mode2, top, tmpDir.path, env, fileName, rand);
     isolate =
-        'Isolate (${tmpDir.path}) ${ffi ? "" : "NO-"}FFI ${fp ? "" : "NO-"}FP : '
+        'Isolate (${tmpDir.path}) ${fp ? "" : "NO-"}FP ${ffi ? "" : "NO-"}FFI ${flatTp ? "" : "NO-"}FLAT : '
         '${runner1.description} - ${runner2.description}';
 
     start_time = DateTime.now().millisecondsSinceEpoch;
@@ -376,6 +377,9 @@
       (mode2.startsWith('jit') || mode2.startsWith('kbc')) &&
       (!mode1.contains('arm') && !mode2.contains('arm'));
 
+  bool nestedTypesAllowed(String mode1, String mode2) =>
+      (!mode1.contains('arm') && !mode2.contains('arm'));
+
   bool timeIsUp() {
     if (time > 0) {
       current_time = DateTime.now().millisecondsSinceEpoch;
@@ -404,7 +408,7 @@
 
   void generateTest() {
     final file = File(fileName).openSync(mode: FileMode.write);
-    DartFuzz(seed, fp, ffi, file).run();
+    DartFuzz(seed, fp, ffi, flatTp, file).run();
     file.closeSync();
   }
 
@@ -514,7 +518,8 @@
 
   void showReproduce() {
     print("\n-- BEGIN REPRODUCE  --\n");
-    print("dartfuzz.dart --${ffi ? "" : "no-"}ffi --${fp ? "" : "no-"}fp "
+    print("dartfuzz.dart --${fp ? "" : "no-"}fp --${ffi ? "" : "no-"}ffi "
+        "--${flatTp ? "" : "no-"}flat "
         "--seed ${seed} $fileName");
     print("\n-- RUN 1 --\n");
     runner1.printReproductionCommand();
@@ -542,6 +547,7 @@
   TestRunner runner2;
   bool fp;
   bool ffi;
+  bool flatTp;
   String isolate;
   int seed;
 
diff --git a/runtime/tools/dartfuzz/dartfuzz_type_table.dart b/runtime/tools/dartfuzz/dartfuzz_type_table.dart
new file mode 100644
index 0000000..bcd16d2
--- /dev/null
+++ b/runtime/tools/dartfuzz/dartfuzz_type_table.dart
@@ -0,0 +1,7825 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Class that represents some common Dart types.
+///
+/// NOTE: this code has been generated automatically.
+///
+class DartType {
+  final String name;
+  const DartType._withName(this.name);
+  factory DartType.fromDartConfig(
+      {bool enableFp = false, bool disableNesting = false}) {
+    if (enableFp && !disableNesting) {
+      return DartType();
+    } else if (!enableFp && !disableNesting) {
+      return DartTypeNoFp();
+    } else if (enableFp && disableNesting) {
+      return DartTypeFlatTp();
+    } else {
+      return DartTypeNoFpFlatTp();
+    }
+  }
+  const DartType() : name = null;
+  static bool isListType(DartType tp) {
+    return DartType._listTypes.contains(tp);
+  }
+
+  static bool isMapType(DartType tp) {
+    return DartType._mapTypes.contains(tp);
+  }
+
+  static bool isCollectionType(DartType tp) {
+    return DartType._collectionTypes.contains(tp);
+  }
+
+  static bool isGrowableType(DartType tp) {
+    return DartType._growableTypes.contains(tp);
+  }
+
+  static bool isComplexType(DartType tp) {
+    return DartType._complexTypes.contains(tp);
+  }
+
+  bool isInterfaceOfType(DartType tp, DartType iTp) {
+    return _interfaceRels.containsKey(iTp) && _interfaceRels[iTp].contains(tp);
+  }
+
+  Set<DartType> get mapTypes {
+    return _mapTypes;
+  }
+
+  bool isSpecializable(DartType tp) {
+    return _interfaceRels.containsKey(tp);
+  }
+
+  Set<DartType> interfaces(DartType tp) {
+    if (_interfaceRels.containsKey(tp)) {
+      return _interfaceRels[tp];
+    }
+    return null;
+  }
+
+  DartType indexType(DartType tp) {
+    if (_indexedBy.containsKey(tp)) {
+      return _indexedBy[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> indexableElementTypes(DartType tp) {
+    if (_indexableElementOf.containsKey(tp)) {
+      return _indexableElementOf[tp];
+    }
+    return null;
+  }
+
+  bool isIndexableElementType(DartType tp) {
+    return _indexableElementOf.containsKey(tp);
+  }
+
+  DartType elementType(DartType tp) {
+    if (_subscriptsTo.containsKey(tp)) {
+      return _subscriptsTo[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> get iterableTypes1 {
+    return _iterableTypes1;
+  }
+
+  Set<String> uniOps(DartType tp) {
+    if (_uniOps.containsKey(tp)) {
+      return _uniOps[tp];
+    }
+    return <String>{};
+  }
+
+  Set<String> binOps(DartType tp) {
+    if (_binOps.containsKey(tp)) {
+      return _binOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<List<DartType>> binOpParameters(DartType tp, String op) {
+    if (_binOps.containsKey(tp) && _binOps[tp].containsKey(op)) {
+      return _binOps[tp][op];
+    }
+    return null;
+  }
+
+  Set<String> assignOps(DartType tp) {
+    if (_assignOps.containsKey(tp)) {
+      return _assignOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<DartType> assignOpRhs(DartType tp, String op) {
+    if (_assignOps.containsKey(tp) && _assignOps[tp].containsKey(op)) {
+      return _assignOps[tp][op];
+    }
+    return <DartType>{};
+  }
+
+  bool hasConstructor(DartType tp) {
+    return _constructors.containsKey(tp);
+  }
+
+  Set<String> constructors(DartType tp) {
+    if (_constructors.containsKey(tp)) {
+      return _constructors[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  List<DartType> constructorParameters(DartType tp, String constructor) {
+    if (_constructors.containsKey(tp) &&
+        _constructors[tp].containsKey(constructor)) {
+      return _constructors[tp][constructor];
+    }
+    return null;
+  }
+
+  Set<DartType> get allTypes {
+    return _allTypes;
+  }
+
+  static const INT8LIST = const DartType._withName("Int8List");
+  static const UINT8LIST = const DartType._withName("Uint8List");
+  static const UINT8CLAMPEDLIST = const DartType._withName("Uint8ClampedList");
+  static const INT16LIST = const DartType._withName("Int16List");
+  static const UINT16LIST = const DartType._withName("Uint16List");
+  static const INT32LIST = const DartType._withName("Int32List");
+  static const UINT32LIST = const DartType._withName("Uint32List");
+  static const INT64LIST = const DartType._withName("Int64List");
+  static const UINT64LIST = const DartType._withName("Uint64List");
+  static const FLOAT32LIST = const DartType._withName("Float32List");
+  static const FLOAT64LIST = const DartType._withName("Float64List");
+  static const FLOAT32X4LIST = const DartType._withName("Float32x4List");
+  static const INT32X4LIST = const DartType._withName("Int32x4List");
+  static const FLOAT64X2LIST = const DartType._withName("Float64x2List");
+  static const FLOAT32X4 = const DartType._withName("Float32x4");
+  static const INT32X4 = const DartType._withName("Int32x4");
+  static const FLOAT64X2 = const DartType._withName("Float64x2");
+  static const BOOL = const DartType._withName("bool");
+  static const DOUBLE = const DartType._withName("double");
+  static const DURATION = const DartType._withName("Duration");
+  static const INT = const DartType._withName("int");
+  static const NUM = const DartType._withName("num");
+  static const STRING = const DartType._withName("String");
+  static const LIST_BOOL = const DartType._withName("List<bool>");
+  static const LIST_DOUBLE = const DartType._withName("List<double>");
+  static const LIST_INT = const DartType._withName("List<int>");
+  static const LIST_STRING = const DartType._withName("List<String>");
+  static const SET_BOOL = const DartType._withName("Set<bool>");
+  static const SET_DOUBLE = const DartType._withName("Set<double>");
+  static const SET_INT = const DartType._withName("Set<int>");
+  static const SET_STRING = const DartType._withName("Set<String>");
+  static const MAP_BOOL_BOOL = const DartType._withName("Map<bool, bool>");
+  static const MAP_BOOL_DOUBLE = const DartType._withName("Map<bool, double>");
+  static const MAP_BOOL_INT = const DartType._withName("Map<bool, int>");
+  static const MAP_BOOL_STRING = const DartType._withName("Map<bool, String>");
+  static const MAP_DOUBLE_BOOL = const DartType._withName("Map<double, bool>");
+  static const MAP_DOUBLE_DOUBLE =
+      const DartType._withName("Map<double, double>");
+  static const MAP_DOUBLE_INT = const DartType._withName("Map<double, int>");
+  static const MAP_DOUBLE_STRING =
+      const DartType._withName("Map<double, String>");
+  static const MAP_INT_BOOL = const DartType._withName("Map<int, bool>");
+  static const MAP_INT_DOUBLE = const DartType._withName("Map<int, double>");
+  static const MAP_INT_INT = const DartType._withName("Map<int, int>");
+  static const MAP_INT_STRING = const DartType._withName("Map<int, String>");
+  static const MAP_STRING_BOOL = const DartType._withName("Map<String, bool>");
+  static const MAP_STRING_DOUBLE =
+      const DartType._withName("Map<String, double>");
+  static const MAP_STRING_INT = const DartType._withName("Map<String, int>");
+  static const MAP_STRING_STRING =
+      const DartType._withName("Map<String, String>");
+  static const LIST_MAP_STRING_INT =
+      const DartType._withName("List<Map<String, int>>");
+  static const SET_MAP_STRING_BOOL =
+      const DartType._withName("Set<Map<String, bool>>");
+  static const MAP_BOOL_MAP_INT_INT =
+      const DartType._withName("Map<bool, Map<int, int>>");
+  static const MAP_DOUBLE_MAP_INT_DOUBLE =
+      const DartType._withName("Map<double, Map<int, double>>");
+  static const MAP_INT_MAP_DOUBLE_STRING =
+      const DartType._withName("Map<int, Map<double, String>>");
+  static const MAP_STRING_MAP_DOUBLE_DOUBLE =
+      const DartType._withName("Map<String, Map<double, double>>");
+  static const MAP_LIST_BOOL_MAP_BOOL_STRING =
+      const DartType._withName("Map<List<bool>, Map<bool, String>>");
+  static const MAP_LIST_DOUBLE_MAP_BOOL_INT =
+      const DartType._withName("Map<List<double>, Map<bool, int>>");
+  static const MAP_LIST_INT_MAP_BOOL_BOOL =
+      const DartType._withName("Map<List<int>, Map<bool, bool>>");
+  static const MAP_LIST_STRING_SET_INT =
+      const DartType._withName("Map<List<String>, Set<int>>");
+  static const MAP_SET_BOOL_SET_BOOL =
+      const DartType._withName("Map<Set<bool>, Set<bool>>");
+  static const MAP_SET_DOUBLE_LIST_STRING =
+      const DartType._withName("Map<Set<double>, List<String>>");
+  static const MAP_SET_INT_LIST_DOUBLE =
+      const DartType._withName("Map<Set<int>, List<double>>");
+  static const MAP_SET_STRING_STRING =
+      const DartType._withName("Map<Set<String>, String>");
+  static const MAP_MAP_BOOL_BOOL_DOUBLE =
+      const DartType._withName("Map<Map<bool, bool>, double>");
+  static const MAP_MAP_BOOL_DOUBLE_BOOL =
+      const DartType._withName("Map<Map<bool, double>, bool>");
+  static const MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT =
+      const DartType._withName("Map<Map<bool, double>, Map<String, int>>");
+  static const MAP_MAP_BOOL_INT_MAP_STRING_BOOL =
+      const DartType._withName("Map<Map<bool, int>, Map<String, bool>>");
+  static const MAP_MAP_BOOL_STRING_MAP_INT_INT =
+      const DartType._withName("Map<Map<bool, String>, Map<int, int>>");
+  static const MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE =
+      const DartType._withName("Map<Map<double, bool>, Map<int, double>>");
+  static const MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING =
+      const DartType._withName("Map<Map<double, double>, Map<double, String>>");
+  static const MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE =
+      const DartType._withName("Map<Map<double, int>, Map<double, double>>");
+  static const MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING =
+      const DartType._withName("Map<Map<double, String>, Map<bool, String>>");
+  static const MAP_MAP_INT_BOOL_MAP_BOOL_INT =
+      const DartType._withName("Map<Map<int, bool>, Map<bool, int>>");
+  static const MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL =
+      const DartType._withName("Map<Map<int, double>, Map<bool, bool>>");
+  static const MAP_MAP_INT_INT_SET_INT =
+      const DartType._withName("Map<Map<int, int>, Set<int>>");
+  static const MAP_MAP_INT_STRING_SET_BOOL =
+      const DartType._withName("Map<Map<int, String>, Set<bool>>");
+  static const MAP_MAP_STRING_BOOL_LIST_STRING =
+      const DartType._withName("Map<Map<String, bool>, List<String>>");
+  static const MAP_MAP_STRING_DOUBLE_LIST_DOUBLE =
+      const DartType._withName("Map<Map<String, double>, List<double>>");
+  static const MAP_MAP_STRING_INT_STRING =
+      const DartType._withName("Map<Map<String, int>, String>");
+  static const MAP_MAP_STRING_STRING_DOUBLE =
+      const DartType._withName("Map<Map<String, String>, double>");
+
+  // NON INSTANTIABLE
+  static const EFFICIENTLENGTHITERABLE_INT =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_INT");
+  static const _TYPEDINTLIST = const DartType._withName("___TYPEDINTLIST");
+  static const OBJECT = const DartType._withName("__OBJECT");
+  static const TYPEDDATA = const DartType._withName("__TYPEDDATA");
+  static const ITERABLE_INT = const DartType._withName("__ITERABLE_INT");
+  static const EFFICIENTLENGTHITERABLE_DOUBLE =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_DOUBLE");
+  static const _TYPEDFLOATLIST = const DartType._withName("___TYPEDFLOATLIST");
+  static const ITERABLE_DOUBLE = const DartType._withName("__ITERABLE_DOUBLE");
+  static const LIST_FLOAT32X4 = const DartType._withName("__LIST_FLOAT32X4");
+  static const EFFICIENTLENGTHITERABLE_FLOAT32X4 =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_FLOAT32X4");
+  static const ITERABLE_FLOAT32X4 =
+      const DartType._withName("__ITERABLE_FLOAT32X4");
+  static const LIST_INT32X4 = const DartType._withName("__LIST_INT32X4");
+  static const EFFICIENTLENGTHITERABLE_INT32X4 =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_INT32X4");
+  static const ITERABLE_INT32X4 =
+      const DartType._withName("__ITERABLE_INT32X4");
+  static const LIST_FLOAT64X2 = const DartType._withName("__LIST_FLOAT64X2");
+  static const EFFICIENTLENGTHITERABLE_FLOAT64X2 =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_FLOAT64X2");
+  static const ITERABLE_FLOAT64X2 =
+      const DartType._withName("__ITERABLE_FLOAT64X2");
+  static const COMPARABLE_NUM = const DartType._withName("__COMPARABLE_NUM");
+  static const COMPARABLE_DURATION =
+      const DartType._withName("__COMPARABLE_DURATION");
+  static const COMPARABLE_STRING =
+      const DartType._withName("__COMPARABLE_STRING");
+  static const PATTERN = const DartType._withName("__PATTERN");
+  static const EFFICIENTLENGTHITERABLE_BOOL =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_BOOL");
+  static const EFFICIENTLENGTHITERABLE_E =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_E");
+  static const ITERABLE_E = const DartType._withName("__ITERABLE_E");
+  static const EFFICIENTLENGTHITERABLE_STRING =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_STRING");
+  static const EFFICIENTLENGTHITERABLE_MAP_STRING_INT =
+      const DartType._withName("__EFFICIENTLENGTHITERABLE_MAP_STRING_INT");
+
+  // All types extracted from analyzer.
+  static const _allTypes = {
+    INT8LIST,
+    UINT8LIST,
+    UINT8CLAMPEDLIST,
+    INT16LIST,
+    UINT16LIST,
+    INT32LIST,
+    UINT32LIST,
+    INT64LIST,
+    UINT64LIST,
+    FLOAT32LIST,
+    FLOAT64LIST,
+    FLOAT32X4LIST,
+    INT32X4LIST,
+    FLOAT64X2LIST,
+    FLOAT32X4,
+    INT32X4,
+    FLOAT64X2,
+    BOOL,
+    DOUBLE,
+    DURATION,
+    INT,
+    NUM,
+    STRING,
+    LIST_BOOL,
+    LIST_DOUBLE,
+    LIST_INT,
+    LIST_STRING,
+    SET_BOOL,
+    SET_DOUBLE,
+    SET_INT,
+    SET_STRING,
+    MAP_BOOL_BOOL,
+    MAP_BOOL_DOUBLE,
+    MAP_BOOL_INT,
+    MAP_BOOL_STRING,
+    MAP_DOUBLE_BOOL,
+    MAP_DOUBLE_DOUBLE,
+    MAP_DOUBLE_INT,
+    MAP_DOUBLE_STRING,
+    MAP_INT_BOOL,
+    MAP_INT_DOUBLE,
+    MAP_INT_INT,
+    MAP_INT_STRING,
+    MAP_STRING_BOOL,
+    MAP_STRING_DOUBLE,
+    MAP_STRING_INT,
+    MAP_STRING_STRING,
+    LIST_MAP_STRING_INT,
+    SET_MAP_STRING_BOOL,
+    MAP_BOOL_MAP_INT_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    MAP_LIST_BOOL_MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT,
+    MAP_SET_BOOL_SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_SET_STRING_STRING,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING,
+    MAP_MAP_STRING_STRING_DOUBLE,
+  };
+
+  // All List<E> types: LIST_INT, LIST_STRING, etc.
+  static const Set<DartType> _listTypes = {
+    FLOAT32LIST,
+    FLOAT32X4LIST,
+    FLOAT64LIST,
+    FLOAT64X2LIST,
+    INT16LIST,
+    INT32LIST,
+    INT32X4LIST,
+    INT64LIST,
+    INT8LIST,
+    LIST_BOOL,
+    LIST_DOUBLE,
+    LIST_INT,
+    LIST_MAP_STRING_INT,
+    LIST_STRING,
+    UINT16LIST,
+    UINT32LIST,
+    UINT64LIST,
+    UINT8CLAMPEDLIST,
+    UINT8LIST,
+  };
+
+  // All Set types: SET_INT, SET_STRING, etc.
+  static const Set<DartType> _setTypes = {
+    SET_BOOL,
+    SET_DOUBLE,
+    SET_INT,
+    SET_MAP_STRING_BOOL,
+    SET_STRING,
+  };
+
+  // All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
+  static const Set<DartType> _mapTypes = {
+    MAP_BOOL_BOOL,
+    MAP_BOOL_DOUBLE,
+    MAP_BOOL_INT,
+    MAP_BOOL_MAP_INT_INT,
+    MAP_BOOL_STRING,
+    MAP_DOUBLE_BOOL,
+    MAP_DOUBLE_DOUBLE,
+    MAP_DOUBLE_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_DOUBLE_STRING,
+    MAP_INT_BOOL,
+    MAP_INT_DOUBLE,
+    MAP_INT_INT,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_INT_STRING,
+    MAP_LIST_BOOL_MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING,
+    MAP_MAP_STRING_STRING_DOUBLE,
+    MAP_SET_BOOL_SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_SET_STRING_STRING,
+    MAP_STRING_BOOL,
+    MAP_STRING_DOUBLE,
+    MAP_STRING_INT,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    MAP_STRING_STRING,
+  };
+
+  // All collection types: list, map and set types.
+  static const Set<DartType> _collectionTypes = {
+    FLOAT32LIST,
+    FLOAT32X4LIST,
+    FLOAT64LIST,
+    FLOAT64X2LIST,
+    INT16LIST,
+    INT32LIST,
+    INT32X4LIST,
+    INT64LIST,
+    INT8LIST,
+    LIST_BOOL,
+    LIST_DOUBLE,
+    LIST_INT,
+    LIST_MAP_STRING_INT,
+    LIST_STRING,
+    MAP_BOOL_BOOL,
+    MAP_BOOL_DOUBLE,
+    MAP_BOOL_INT,
+    MAP_BOOL_MAP_INT_INT,
+    MAP_BOOL_STRING,
+    MAP_DOUBLE_BOOL,
+    MAP_DOUBLE_DOUBLE,
+    MAP_DOUBLE_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_DOUBLE_STRING,
+    MAP_INT_BOOL,
+    MAP_INT_DOUBLE,
+    MAP_INT_INT,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_INT_STRING,
+    MAP_LIST_BOOL_MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING,
+    MAP_MAP_STRING_STRING_DOUBLE,
+    MAP_SET_BOOL_SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_SET_STRING_STRING,
+    MAP_STRING_BOOL,
+    MAP_STRING_DOUBLE,
+    MAP_STRING_INT,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    MAP_STRING_STRING,
+    SET_BOOL,
+    SET_DOUBLE,
+    SET_INT,
+    SET_MAP_STRING_BOOL,
+    SET_STRING,
+    UINT16LIST,
+    UINT32LIST,
+    UINT64LIST,
+    UINT8CLAMPEDLIST,
+    UINT8LIST,
+  };
+
+  // All growable types: list, map, set and string types.
+  static const Set<DartType> _growableTypes = {
+    FLOAT32LIST,
+    FLOAT32X4LIST,
+    FLOAT64LIST,
+    FLOAT64X2LIST,
+    INT16LIST,
+    INT32LIST,
+    INT32X4LIST,
+    INT64LIST,
+    INT8LIST,
+    LIST_BOOL,
+    LIST_DOUBLE,
+    LIST_INT,
+    LIST_MAP_STRING_INT,
+    LIST_STRING,
+    MAP_BOOL_BOOL,
+    MAP_BOOL_DOUBLE,
+    MAP_BOOL_INT,
+    MAP_BOOL_MAP_INT_INT,
+    MAP_BOOL_STRING,
+    MAP_DOUBLE_BOOL,
+    MAP_DOUBLE_DOUBLE,
+    MAP_DOUBLE_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_DOUBLE_STRING,
+    MAP_INT_BOOL,
+    MAP_INT_DOUBLE,
+    MAP_INT_INT,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_INT_STRING,
+    MAP_LIST_BOOL_MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING,
+    MAP_MAP_STRING_STRING_DOUBLE,
+    MAP_SET_BOOL_SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_SET_STRING_STRING,
+    MAP_STRING_BOOL,
+    MAP_STRING_DOUBLE,
+    MAP_STRING_INT,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    MAP_STRING_STRING,
+    SET_BOOL,
+    SET_DOUBLE,
+    SET_INT,
+    SET_MAP_STRING_BOOL,
+    SET_STRING,
+    STRING,
+    UINT16LIST,
+    UINT32LIST,
+    UINT64LIST,
+    UINT8CLAMPEDLIST,
+    UINT8LIST,
+  };
+
+  // All floating point types: DOUBLE, SET_DOUBLE, MAP_X_DOUBLE, etc.
+  static const Set<DartType> _fpTypes = {
+    DOUBLE,
+    FLOAT32LIST,
+    FLOAT32X4,
+    FLOAT32X4LIST,
+    FLOAT64LIST,
+    FLOAT64X2,
+    FLOAT64X2LIST,
+    LIST_DOUBLE,
+    MAP_BOOL_DOUBLE,
+    MAP_DOUBLE_BOOL,
+    MAP_DOUBLE_DOUBLE,
+    MAP_DOUBLE_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_DOUBLE_STRING,
+    MAP_INT_DOUBLE,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_STRING_DOUBLE,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_STRING_DOUBLE,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    SET_DOUBLE,
+  };
+
+  // All trivially indexable types: Map types and List types.
+  // Elements of these can be written and read by [], unlike Set
+  // which uses getElementAt to access individual elements.
+  static const Set<DartType> _indexableTypes = {
+    FLOAT32LIST,
+    FLOAT32X4LIST,
+    FLOAT64LIST,
+    FLOAT64X2LIST,
+    INT16LIST,
+    INT32LIST,
+    INT32X4LIST,
+    INT64LIST,
+    INT8LIST,
+    LIST_BOOL,
+    LIST_DOUBLE,
+    LIST_INT,
+    LIST_MAP_STRING_INT,
+    LIST_STRING,
+    MAP_BOOL_BOOL,
+    MAP_BOOL_DOUBLE,
+    MAP_BOOL_INT,
+    MAP_BOOL_MAP_INT_INT,
+    MAP_BOOL_STRING,
+    MAP_DOUBLE_BOOL,
+    MAP_DOUBLE_DOUBLE,
+    MAP_DOUBLE_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_DOUBLE_STRING,
+    MAP_INT_BOOL,
+    MAP_INT_DOUBLE,
+    MAP_INT_INT,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_INT_STRING,
+    MAP_LIST_BOOL_MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING,
+    MAP_MAP_STRING_STRING_DOUBLE,
+    MAP_SET_BOOL_SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_SET_STRING_STRING,
+    MAP_STRING_BOOL,
+    MAP_STRING_DOUBLE,
+    MAP_STRING_INT,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    MAP_STRING_STRING,
+    UINT16LIST,
+    UINT32LIST,
+    UINT64LIST,
+    UINT8CLAMPEDLIST,
+    UINT8LIST,
+  };
+
+  // Map type to the resulting type when subscripted.
+  // Example: List<String> subscripts to String.
+  static const Map<DartType, DartType> _subscriptsTo = {
+    DURATION: DURATION,
+    FLOAT32LIST: DOUBLE,
+    FLOAT32X4LIST: FLOAT32X4,
+    FLOAT64LIST: DOUBLE,
+    FLOAT64X2LIST: FLOAT64X2,
+    INT16LIST: INT,
+    INT32LIST: INT,
+    INT32X4LIST: INT32X4,
+    INT64LIST: INT,
+    INT8LIST: INT,
+    LIST_BOOL: BOOL,
+    LIST_DOUBLE: DOUBLE,
+    LIST_INT: INT,
+    LIST_MAP_STRING_INT: MAP_STRING_INT,
+    LIST_STRING: STRING,
+    MAP_BOOL_BOOL: BOOL,
+    MAP_BOOL_DOUBLE: DOUBLE,
+    MAP_BOOL_INT: INT,
+    MAP_BOOL_MAP_INT_INT: MAP_INT_INT,
+    MAP_BOOL_STRING: STRING,
+    MAP_DOUBLE_BOOL: BOOL,
+    MAP_DOUBLE_DOUBLE: DOUBLE,
+    MAP_DOUBLE_INT: INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE: MAP_INT_DOUBLE,
+    MAP_DOUBLE_STRING: STRING,
+    MAP_INT_BOOL: BOOL,
+    MAP_INT_DOUBLE: DOUBLE,
+    MAP_INT_INT: INT,
+    MAP_INT_MAP_DOUBLE_STRING: MAP_DOUBLE_STRING,
+    MAP_INT_STRING: STRING,
+    MAP_LIST_BOOL_MAP_BOOL_STRING: MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT: MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL: MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT: SET_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE: DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL: BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT: MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL: MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT: MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE: MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING: MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE: MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING: MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT: MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL: MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT: SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL: SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING: LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE: LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING: STRING,
+    MAP_MAP_STRING_STRING_DOUBLE: DOUBLE,
+    MAP_SET_BOOL_SET_BOOL: SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING: LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE: LIST_DOUBLE,
+    MAP_SET_STRING_STRING: STRING,
+    MAP_STRING_BOOL: BOOL,
+    MAP_STRING_DOUBLE: DOUBLE,
+    MAP_STRING_INT: INT,
+    MAP_STRING_MAP_DOUBLE_DOUBLE: MAP_DOUBLE_DOUBLE,
+    MAP_STRING_STRING: STRING,
+    NUM: NUM,
+    SET_BOOL: BOOL,
+    SET_DOUBLE: DOUBLE,
+    SET_INT: INT,
+    SET_MAP_STRING_BOOL: MAP_STRING_BOOL,
+    SET_STRING: STRING,
+    STRING: STRING,
+    UINT16LIST: INT,
+    UINT32LIST: INT,
+    UINT64LIST: INT,
+    UINT8CLAMPEDLIST: INT,
+    UINT8LIST: INT,
+  };
+
+  // Map type to type required as index.
+  // Example: List<String> is indexed by int,
+  // Map<String, double> indexed by String.
+  static const Map<DartType, DartType> _indexedBy = {
+    FLOAT32LIST: INT,
+    FLOAT32X4LIST: INT,
+    FLOAT64LIST: INT,
+    FLOAT64X2LIST: INT,
+    INT16LIST: INT,
+    INT32LIST: INT,
+    INT32X4LIST: INT,
+    INT64LIST: INT,
+    INT8LIST: INT,
+    LIST_BOOL: INT,
+    LIST_DOUBLE: INT,
+    LIST_INT: INT,
+    LIST_MAP_STRING_INT: INT,
+    LIST_STRING: INT,
+    MAP_BOOL_BOOL: BOOL,
+    MAP_BOOL_DOUBLE: BOOL,
+    MAP_BOOL_INT: BOOL,
+    MAP_BOOL_MAP_INT_INT: BOOL,
+    MAP_BOOL_STRING: BOOL,
+    MAP_DOUBLE_BOOL: DOUBLE,
+    MAP_DOUBLE_DOUBLE: DOUBLE,
+    MAP_DOUBLE_INT: DOUBLE,
+    MAP_DOUBLE_MAP_INT_DOUBLE: DOUBLE,
+    MAP_DOUBLE_STRING: DOUBLE,
+    MAP_INT_BOOL: INT,
+    MAP_INT_DOUBLE: INT,
+    MAP_INT_INT: INT,
+    MAP_INT_MAP_DOUBLE_STRING: INT,
+    MAP_INT_STRING: INT,
+    MAP_LIST_BOOL_MAP_BOOL_STRING: LIST_BOOL,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT: LIST_DOUBLE,
+    MAP_LIST_INT_MAP_BOOL_BOOL: LIST_INT,
+    MAP_LIST_STRING_SET_INT: LIST_STRING,
+    MAP_MAP_BOOL_BOOL_DOUBLE: MAP_BOOL_BOOL,
+    MAP_MAP_BOOL_DOUBLE_BOOL: MAP_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT: MAP_BOOL_DOUBLE,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL: MAP_BOOL_INT,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT: MAP_BOOL_STRING,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE: MAP_DOUBLE_BOOL,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING: MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE: MAP_DOUBLE_INT,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING: MAP_DOUBLE_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT: MAP_INT_BOOL,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL: MAP_INT_DOUBLE,
+    MAP_MAP_INT_INT_SET_INT: MAP_INT_INT,
+    MAP_MAP_INT_STRING_SET_BOOL: MAP_INT_STRING,
+    MAP_MAP_STRING_BOOL_LIST_STRING: MAP_STRING_BOOL,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE: MAP_STRING_DOUBLE,
+    MAP_MAP_STRING_INT_STRING: MAP_STRING_INT,
+    MAP_MAP_STRING_STRING_DOUBLE: MAP_STRING_STRING,
+    MAP_SET_BOOL_SET_BOOL: SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING: SET_DOUBLE,
+    MAP_SET_INT_LIST_DOUBLE: SET_INT,
+    MAP_SET_STRING_STRING: SET_STRING,
+    MAP_STRING_BOOL: STRING,
+    MAP_STRING_DOUBLE: STRING,
+    MAP_STRING_INT: STRING,
+    MAP_STRING_MAP_DOUBLE_DOUBLE: STRING,
+    MAP_STRING_STRING: STRING,
+    UINT16LIST: INT,
+    UINT32LIST: INT,
+    UINT64LIST: INT,
+    UINT8CLAMPEDLIST: INT,
+    UINT8LIST: INT,
+  };
+
+  // Map type to a Set of types that contain it as an element.
+  // Example: String is element of List<String> and Map<int, String>
+  static const Map<DartType, Set<DartType>> _elementOf = {
+    BOOL: {
+      LIST_BOOL,
+      MAP_BOOL_BOOL,
+      MAP_DOUBLE_BOOL,
+      MAP_INT_BOOL,
+      MAP_MAP_BOOL_DOUBLE_BOOL,
+      MAP_STRING_BOOL,
+      SET_BOOL,
+    },
+    DOUBLE: {
+      FLOAT32LIST,
+      FLOAT64LIST,
+      LIST_DOUBLE,
+      MAP_BOOL_DOUBLE,
+      MAP_DOUBLE_DOUBLE,
+      MAP_INT_DOUBLE,
+      MAP_MAP_BOOL_BOOL_DOUBLE,
+      MAP_MAP_STRING_STRING_DOUBLE,
+      MAP_STRING_DOUBLE,
+      SET_DOUBLE,
+    },
+    DURATION: {
+      DURATION,
+    },
+    FLOAT32X4: {
+      FLOAT32X4LIST,
+    },
+    FLOAT64X2: {
+      FLOAT64X2LIST,
+    },
+    INT: {
+      INT16LIST,
+      INT32LIST,
+      INT64LIST,
+      INT8LIST,
+      LIST_INT,
+      MAP_BOOL_INT,
+      MAP_DOUBLE_INT,
+      MAP_INT_INT,
+      MAP_STRING_INT,
+      SET_INT,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    INT32X4: {
+      INT32X4LIST,
+    },
+    LIST_DOUBLE: {
+      MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+      MAP_SET_INT_LIST_DOUBLE,
+    },
+    LIST_STRING: {
+      MAP_MAP_STRING_BOOL_LIST_STRING,
+      MAP_SET_DOUBLE_LIST_STRING,
+    },
+    MAP_BOOL_BOOL: {
+      MAP_LIST_INT_MAP_BOOL_BOOL,
+      MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    },
+    MAP_BOOL_INT: {
+      MAP_LIST_DOUBLE_MAP_BOOL_INT,
+      MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    },
+    MAP_BOOL_STRING: {
+      MAP_LIST_BOOL_MAP_BOOL_STRING,
+      MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    },
+    MAP_DOUBLE_DOUBLE: {
+      MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+      MAP_STRING_MAP_DOUBLE_DOUBLE,
+    },
+    MAP_DOUBLE_STRING: {
+      MAP_INT_MAP_DOUBLE_STRING,
+      MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    },
+    MAP_INT_DOUBLE: {
+      MAP_DOUBLE_MAP_INT_DOUBLE,
+      MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    },
+    MAP_INT_INT: {
+      MAP_BOOL_MAP_INT_INT,
+      MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    },
+    MAP_STRING_BOOL: {
+      MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      SET_MAP_STRING_BOOL,
+    },
+    MAP_STRING_INT: {
+      LIST_MAP_STRING_INT,
+      MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    },
+    NUM: {
+      NUM,
+    },
+    SET_BOOL: {
+      MAP_MAP_INT_STRING_SET_BOOL,
+      MAP_SET_BOOL_SET_BOOL,
+    },
+    SET_INT: {
+      MAP_LIST_STRING_SET_INT,
+      MAP_MAP_INT_INT_SET_INT,
+    },
+    STRING: {
+      LIST_STRING,
+      MAP_BOOL_STRING,
+      MAP_DOUBLE_STRING,
+      MAP_INT_STRING,
+      MAP_MAP_STRING_INT_STRING,
+      MAP_SET_STRING_STRING,
+      MAP_STRING_STRING,
+      SET_STRING,
+      STRING,
+    },
+  };
+
+  // Map type to a Set of types that contain it as an indexable element.
+  // Same as element of, but without Set types.
+  static const Map<DartType, Set<DartType>> _indexableElementOf = {
+    BOOL: {
+      LIST_BOOL,
+      MAP_BOOL_BOOL,
+      MAP_DOUBLE_BOOL,
+      MAP_INT_BOOL,
+      MAP_MAP_BOOL_DOUBLE_BOOL,
+      MAP_STRING_BOOL,
+    },
+    DOUBLE: {
+      FLOAT32LIST,
+      FLOAT64LIST,
+      LIST_DOUBLE,
+      MAP_BOOL_DOUBLE,
+      MAP_DOUBLE_DOUBLE,
+      MAP_INT_DOUBLE,
+      MAP_MAP_BOOL_BOOL_DOUBLE,
+      MAP_MAP_STRING_STRING_DOUBLE,
+      MAP_STRING_DOUBLE,
+    },
+    FLOAT32X4: {
+      FLOAT32X4LIST,
+    },
+    FLOAT64X2: {
+      FLOAT64X2LIST,
+    },
+    INT: {
+      INT16LIST,
+      INT32LIST,
+      INT64LIST,
+      INT8LIST,
+      LIST_INT,
+      MAP_BOOL_INT,
+      MAP_DOUBLE_INT,
+      MAP_INT_INT,
+      MAP_STRING_INT,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    INT32X4: {
+      INT32X4LIST,
+    },
+    LIST_DOUBLE: {
+      MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+      MAP_SET_INT_LIST_DOUBLE,
+    },
+    LIST_STRING: {
+      MAP_MAP_STRING_BOOL_LIST_STRING,
+      MAP_SET_DOUBLE_LIST_STRING,
+    },
+    MAP_BOOL_BOOL: {
+      MAP_LIST_INT_MAP_BOOL_BOOL,
+      MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    },
+    MAP_BOOL_INT: {
+      MAP_LIST_DOUBLE_MAP_BOOL_INT,
+      MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    },
+    MAP_BOOL_STRING: {
+      MAP_LIST_BOOL_MAP_BOOL_STRING,
+      MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    },
+    MAP_DOUBLE_DOUBLE: {
+      MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+      MAP_STRING_MAP_DOUBLE_DOUBLE,
+    },
+    MAP_DOUBLE_STRING: {
+      MAP_INT_MAP_DOUBLE_STRING,
+      MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    },
+    MAP_INT_DOUBLE: {
+      MAP_DOUBLE_MAP_INT_DOUBLE,
+      MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    },
+    MAP_INT_INT: {
+      MAP_BOOL_MAP_INT_INT,
+      MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    },
+    MAP_STRING_BOOL: {
+      MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    },
+    MAP_STRING_INT: {
+      LIST_MAP_STRING_INT,
+      MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    },
+    SET_BOOL: {
+      MAP_MAP_INT_STRING_SET_BOOL,
+      MAP_SET_BOOL_SET_BOOL,
+    },
+    SET_INT: {
+      MAP_LIST_STRING_SET_INT,
+      MAP_MAP_INT_INT_SET_INT,
+    },
+    STRING: {
+      LIST_STRING,
+      MAP_BOOL_STRING,
+      MAP_DOUBLE_STRING,
+      MAP_INT_STRING,
+      MAP_MAP_STRING_INT_STRING,
+      MAP_SET_STRING_STRING,
+      MAP_STRING_STRING,
+    },
+  };
+
+  // All iterable types: Set types + List types.
+  // These can be used in for(x in <iterable type>),
+  // therefore Map is not included.
+  static const Set<DartType> _iterableTypes1 = {
+    FLOAT32LIST,
+    FLOAT32X4LIST,
+    FLOAT64LIST,
+    FLOAT64X2LIST,
+    INT16LIST,
+    INT32LIST,
+    INT32X4LIST,
+    INT64LIST,
+    INT8LIST,
+    LIST_BOOL,
+    LIST_DOUBLE,
+    LIST_INT,
+    LIST_MAP_STRING_INT,
+    LIST_STRING,
+    UINT16LIST,
+    UINT32LIST,
+    UINT64LIST,
+    UINT8CLAMPEDLIST,
+    UINT8LIST,
+  };
+
+  // Complex types: Collection types instantiated with nested argument
+  // e.g Map<List<>, >.
+  static const Set<DartType> _complexTypes = {
+    LIST_MAP_STRING_INT,
+    MAP_BOOL_MAP_INT_INT,
+    MAP_DOUBLE_MAP_INT_DOUBLE,
+    MAP_INT_MAP_DOUBLE_STRING,
+    MAP_LIST_BOOL_MAP_BOOL_STRING,
+    MAP_LIST_DOUBLE_MAP_BOOL_INT,
+    MAP_LIST_INT_MAP_BOOL_BOOL,
+    MAP_LIST_STRING_SET_INT,
+    MAP_MAP_BOOL_BOOL_DOUBLE,
+    MAP_MAP_BOOL_DOUBLE_BOOL,
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+    MAP_MAP_INT_INT_SET_INT,
+    MAP_MAP_INT_STRING_SET_BOOL,
+    MAP_MAP_STRING_BOOL_LIST_STRING,
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+    MAP_MAP_STRING_INT_STRING,
+    MAP_MAP_STRING_STRING_DOUBLE,
+    MAP_SET_BOOL_SET_BOOL,
+    MAP_SET_DOUBLE_LIST_STRING,
+    MAP_SET_INT_LIST_DOUBLE,
+    MAP_SET_STRING_STRING,
+    MAP_STRING_MAP_DOUBLE_DOUBLE,
+    SET_MAP_STRING_BOOL,
+  };
+
+  // Map Interface type to Set of types that implement it.
+  // Example: interface num is implemented by int and double.
+  static const Map<DartType, Set<DartType>> _interfaceRels = {
+    COMPARABLE_DURATION: {
+      DURATION,
+    },
+    COMPARABLE_NUM: {
+      DOUBLE,
+      INT,
+      NUM,
+    },
+    COMPARABLE_STRING: {
+      STRING,
+    },
+    EFFICIENTLENGTHITERABLE_BOOL: {
+      LIST_BOOL,
+    },
+    EFFICIENTLENGTHITERABLE_DOUBLE: {
+      FLOAT32LIST,
+      FLOAT64LIST,
+      LIST_DOUBLE,
+    },
+    EFFICIENTLENGTHITERABLE_E: {
+      LIST_BOOL,
+      LIST_DOUBLE,
+      LIST_INT,
+      LIST_MAP_STRING_INT,
+      LIST_STRING,
+      SET_BOOL,
+      SET_DOUBLE,
+      SET_INT,
+      SET_MAP_STRING_BOOL,
+      SET_STRING,
+    },
+    EFFICIENTLENGTHITERABLE_FLOAT32X4: {
+      FLOAT32X4LIST,
+    },
+    EFFICIENTLENGTHITERABLE_FLOAT64X2: {
+      FLOAT64X2LIST,
+    },
+    EFFICIENTLENGTHITERABLE_INT: {
+      INT16LIST,
+      INT32LIST,
+      INT64LIST,
+      INT8LIST,
+      LIST_INT,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    EFFICIENTLENGTHITERABLE_INT32X4: {
+      INT32X4LIST,
+    },
+    EFFICIENTLENGTHITERABLE_MAP_STRING_INT: {
+      LIST_MAP_STRING_INT,
+    },
+    EFFICIENTLENGTHITERABLE_STRING: {
+      LIST_STRING,
+    },
+    ITERABLE_DOUBLE: {
+      FLOAT32LIST,
+      FLOAT64LIST,
+    },
+    ITERABLE_E: {
+      LIST_BOOL,
+      LIST_DOUBLE,
+      LIST_INT,
+      LIST_MAP_STRING_INT,
+      LIST_STRING,
+      SET_BOOL,
+      SET_DOUBLE,
+      SET_INT,
+      SET_MAP_STRING_BOOL,
+      SET_STRING,
+    },
+    ITERABLE_FLOAT32X4: {
+      FLOAT32X4LIST,
+    },
+    ITERABLE_FLOAT64X2: {
+      FLOAT64X2LIST,
+    },
+    ITERABLE_INT: {
+      INT16LIST,
+      INT32LIST,
+      INT64LIST,
+      INT8LIST,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    ITERABLE_INT32X4: {
+      INT32X4LIST,
+    },
+    LIST_DOUBLE: {
+      FLOAT32LIST,
+      FLOAT64LIST,
+      LIST_DOUBLE,
+    },
+    LIST_FLOAT32X4: {
+      FLOAT32X4LIST,
+    },
+    LIST_FLOAT64X2: {
+      FLOAT64X2LIST,
+    },
+    LIST_INT: {
+      INT16LIST,
+      INT32LIST,
+      INT64LIST,
+      INT8LIST,
+      LIST_INT,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    LIST_INT32X4: {
+      INT32X4LIST,
+    },
+    NUM: {
+      DOUBLE,
+      INT,
+      NUM,
+    },
+    OBJECT: {
+      BOOL,
+      DOUBLE,
+      DURATION,
+      FLOAT32LIST,
+      FLOAT32X4,
+      FLOAT32X4LIST,
+      FLOAT64LIST,
+      FLOAT64X2,
+      FLOAT64X2LIST,
+      INT,
+      INT16LIST,
+      INT32LIST,
+      INT32X4,
+      INT32X4LIST,
+      INT64LIST,
+      INT8LIST,
+      LIST_BOOL,
+      LIST_DOUBLE,
+      LIST_INT,
+      LIST_MAP_STRING_INT,
+      LIST_STRING,
+      MAP_BOOL_BOOL,
+      MAP_BOOL_DOUBLE,
+      MAP_BOOL_INT,
+      MAP_BOOL_MAP_INT_INT,
+      MAP_BOOL_STRING,
+      MAP_DOUBLE_BOOL,
+      MAP_DOUBLE_DOUBLE,
+      MAP_DOUBLE_INT,
+      MAP_DOUBLE_MAP_INT_DOUBLE,
+      MAP_DOUBLE_STRING,
+      MAP_INT_BOOL,
+      MAP_INT_DOUBLE,
+      MAP_INT_INT,
+      MAP_INT_MAP_DOUBLE_STRING,
+      MAP_INT_STRING,
+      MAP_LIST_BOOL_MAP_BOOL_STRING,
+      MAP_LIST_DOUBLE_MAP_BOOL_INT,
+      MAP_LIST_INT_MAP_BOOL_BOOL,
+      MAP_LIST_STRING_SET_INT,
+      MAP_MAP_BOOL_BOOL_DOUBLE,
+      MAP_MAP_BOOL_DOUBLE_BOOL,
+      MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+      MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      MAP_MAP_BOOL_STRING_MAP_INT_INT,
+      MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+      MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+      MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+      MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+      MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+      MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+      MAP_MAP_INT_INT_SET_INT,
+      MAP_MAP_INT_STRING_SET_BOOL,
+      MAP_MAP_STRING_BOOL_LIST_STRING,
+      MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+      MAP_MAP_STRING_INT_STRING,
+      MAP_MAP_STRING_STRING_DOUBLE,
+      MAP_SET_BOOL_SET_BOOL,
+      MAP_SET_DOUBLE_LIST_STRING,
+      MAP_SET_INT_LIST_DOUBLE,
+      MAP_SET_STRING_STRING,
+      MAP_STRING_BOOL,
+      MAP_STRING_DOUBLE,
+      MAP_STRING_INT,
+      MAP_STRING_MAP_DOUBLE_DOUBLE,
+      MAP_STRING_STRING,
+      NUM,
+      SET_BOOL,
+      SET_DOUBLE,
+      SET_INT,
+      SET_MAP_STRING_BOOL,
+      SET_STRING,
+      STRING,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    PATTERN: {
+      STRING,
+    },
+    TYPEDDATA: {
+      FLOAT32LIST,
+      FLOAT32X4LIST,
+      FLOAT64LIST,
+      FLOAT64X2LIST,
+      INT16LIST,
+      INT32LIST,
+      INT32X4LIST,
+      INT64LIST,
+      INT8LIST,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+    _TYPEDFLOATLIST: {
+      FLOAT32LIST,
+      FLOAT64LIST,
+    },
+    _TYPEDINTLIST: {
+      INT16LIST,
+      INT32LIST,
+      INT64LIST,
+      INT8LIST,
+      UINT16LIST,
+      UINT32LIST,
+      UINT64LIST,
+      UINT8CLAMPEDLIST,
+      UINT8LIST,
+    },
+  };
+
+  // Map type to a list of constructors names with a list of constructor
+  // parameter types.
+  static const Map<DartType, Map<String, List<DartType>>> _constructors = {
+    DURATION: {
+      '': [],
+    },
+    FLOAT32LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_DOUBLE,
+      ],
+    },
+    FLOAT32X4: {
+      '': [
+        DOUBLE,
+        DOUBLE,
+        DOUBLE,
+        DOUBLE,
+      ],
+      'splat': [
+        DOUBLE,
+      ],
+      'zero': [],
+    },
+    FLOAT32X4LIST: {
+      '': [
+        INT,
+      ],
+    },
+    FLOAT64LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_DOUBLE,
+      ],
+    },
+    FLOAT64X2: {
+      '': [
+        DOUBLE,
+        DOUBLE,
+      ],
+      'splat': [
+        DOUBLE,
+      ],
+      'zero': [],
+    },
+    FLOAT64X2LIST: {
+      '': [
+        INT,
+      ],
+    },
+    INT16LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    INT32LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    INT32X4: {
+      '': [
+        INT,
+        INT,
+        INT,
+        INT,
+      ],
+    },
+    INT32X4LIST: {
+      '': [
+        INT,
+      ],
+    },
+    INT64LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    INT8LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    UINT16LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    UINT32LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    UINT64LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    UINT8CLAMPEDLIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+    UINT8LIST: {
+      '': [
+        INT,
+      ],
+      'fromList': [
+        LIST_INT,
+      ],
+    },
+  };
+
+  // Map type to a list of binary operators with set of the respective
+  // types for the first and second operand.
+  static const Map<DartType, Map<String, Set<List<DartType>>>> _binOps = {
+    BOOL: {
+      '&': {
+        [
+          BOOL,
+          BOOL,
+        ],
+      },
+      '&&': {
+        [
+          BOOL,
+          BOOL,
+        ],
+      },
+      '<': {
+        [
+          DURATION,
+          DURATION,
+        ],
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '<=': {
+        [
+          DURATION,
+          DURATION,
+        ],
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '==': {
+        [
+          NUM,
+          OBJECT,
+        ],
+        [
+          STRING,
+          OBJECT,
+        ],
+        [
+          LIST_BOOL,
+          OBJECT,
+        ],
+        [
+          LIST_DOUBLE,
+          OBJECT,
+        ],
+        [
+          LIST_INT,
+          OBJECT,
+        ],
+        [
+          LIST_STRING,
+          OBJECT,
+        ],
+        [
+          LIST_MAP_STRING_INT,
+          OBJECT,
+        ],
+      },
+      '>': {
+        [
+          DURATION,
+          DURATION,
+        ],
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '>=': {
+        [
+          DURATION,
+          DURATION,
+        ],
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '??': {
+        [
+          BOOL,
+          BOOL,
+        ],
+      },
+      '^': {
+        [
+          BOOL,
+          BOOL,
+        ],
+      },
+      '|': {
+        [
+          BOOL,
+          BOOL,
+        ],
+      },
+      '||': {
+        [
+          BOOL,
+          BOOL,
+        ],
+      },
+    },
+    DOUBLE: {
+      '%': {
+        [
+          DOUBLE,
+          NUM,
+        ],
+      },
+      '*': {
+        [
+          DOUBLE,
+          NUM,
+        ],
+      },
+      '+': {
+        [
+          DOUBLE,
+          NUM,
+        ],
+      },
+      '-': {
+        [
+          DOUBLE,
+          NUM,
+        ],
+      },
+      '/': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '??': {
+        [
+          DOUBLE,
+          DOUBLE,
+        ],
+      },
+    },
+    DURATION: {
+      '*': {
+        [
+          DURATION,
+          NUM,
+        ],
+      },
+      '+': {
+        [
+          DURATION,
+          DURATION,
+        ],
+      },
+      '-': {
+        [
+          DURATION,
+          DURATION,
+        ],
+      },
+      '??': {
+        [
+          DURATION,
+          DURATION,
+        ],
+      },
+      '~/': {
+        [
+          DURATION,
+          INT,
+        ],
+      },
+    },
+    FLOAT32X4: {
+      '*': {
+        [
+          FLOAT32X4,
+          FLOAT32X4,
+        ],
+      },
+      '+': {
+        [
+          FLOAT32X4,
+          FLOAT32X4,
+        ],
+      },
+      '-': {
+        [
+          FLOAT32X4,
+          FLOAT32X4,
+        ],
+      },
+      '/': {
+        [
+          FLOAT32X4,
+          FLOAT32X4,
+        ],
+      },
+      '??': {
+        [
+          FLOAT32X4,
+          FLOAT32X4,
+        ],
+      },
+    },
+    FLOAT64X2: {
+      '*': {
+        [
+          FLOAT64X2,
+          FLOAT64X2,
+        ],
+      },
+      '+': {
+        [
+          FLOAT64X2,
+          FLOAT64X2,
+        ],
+      },
+      '-': {
+        [
+          FLOAT64X2,
+          FLOAT64X2,
+        ],
+      },
+      '/': {
+        [
+          FLOAT64X2,
+          FLOAT64X2,
+        ],
+      },
+      '??': {
+        [
+          FLOAT64X2,
+          FLOAT64X2,
+        ],
+      },
+    },
+    INT: {
+      '&': {
+        [
+          INT,
+          INT,
+        ],
+      },
+      '<<': {
+        [
+          INT,
+          INT,
+        ],
+      },
+      '>>': {
+        [
+          INT,
+          INT,
+        ],
+      },
+      '??': {
+        [
+          INT,
+          INT,
+        ],
+      },
+      '^': {
+        [
+          INT,
+          INT,
+        ],
+      },
+      '|': {
+        [
+          INT,
+          INT,
+        ],
+      },
+      '~/': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+    },
+    INT32X4: {
+      '&': {
+        [
+          INT32X4,
+          INT32X4,
+        ],
+      },
+      '+': {
+        [
+          INT32X4,
+          INT32X4,
+        ],
+      },
+      '-': {
+        [
+          INT32X4,
+          INT32X4,
+        ],
+      },
+      '??': {
+        [
+          INT32X4,
+          INT32X4,
+        ],
+      },
+      '^': {
+        [
+          INT32X4,
+          INT32X4,
+        ],
+      },
+      '|': {
+        [
+          INT32X4,
+          INT32X4,
+        ],
+      },
+    },
+    LIST_BOOL: {
+      '+': {
+        [
+          LIST_BOOL,
+          LIST_BOOL,
+        ],
+      },
+      '??': {
+        [
+          LIST_BOOL,
+          LIST_BOOL,
+        ],
+      },
+    },
+    LIST_DOUBLE: {
+      '+': {
+        [
+          LIST_DOUBLE,
+          LIST_DOUBLE,
+        ],
+      },
+      '??': {
+        [
+          LIST_DOUBLE,
+          LIST_DOUBLE,
+        ],
+      },
+    },
+    LIST_FLOAT32X4: {
+      '+': {
+        [
+          FLOAT32X4LIST,
+          LIST_FLOAT32X4,
+        ],
+      },
+      '??': {
+        [
+          LIST_FLOAT32X4,
+          LIST_FLOAT32X4,
+        ],
+      },
+    },
+    LIST_FLOAT64X2: {
+      '+': {
+        [
+          FLOAT64X2LIST,
+          LIST_FLOAT64X2,
+        ],
+      },
+      '??': {
+        [
+          LIST_FLOAT64X2,
+          LIST_FLOAT64X2,
+        ],
+      },
+    },
+    LIST_INT: {
+      '+': {
+        [
+          LIST_INT,
+          LIST_INT,
+        ],
+      },
+      '??': {
+        [
+          LIST_INT,
+          LIST_INT,
+        ],
+      },
+    },
+    LIST_INT32X4: {
+      '+': {
+        [
+          INT32X4LIST,
+          LIST_INT32X4,
+        ],
+      },
+      '??': {
+        [
+          LIST_INT32X4,
+          LIST_INT32X4,
+        ],
+      },
+    },
+    LIST_MAP_STRING_INT: {
+      '+': {
+        [
+          LIST_MAP_STRING_INT,
+          LIST_MAP_STRING_INT,
+        ],
+      },
+      '??': {
+        [
+          LIST_MAP_STRING_INT,
+          LIST_MAP_STRING_INT,
+        ],
+      },
+    },
+    LIST_STRING: {
+      '+': {
+        [
+          LIST_STRING,
+          LIST_STRING,
+        ],
+      },
+      '??': {
+        [
+          LIST_STRING,
+          LIST_STRING,
+        ],
+      },
+    },
+    NUM: {
+      '%': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '*': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '+': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '-': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+      '??': {
+        [
+          NUM,
+          NUM,
+        ],
+      },
+    },
+    STRING: {
+      '*': {
+        [
+          STRING,
+          INT,
+        ],
+      },
+      '+': {
+        [
+          STRING,
+          STRING,
+        ],
+      },
+      '??': {
+        [
+          STRING,
+          STRING,
+        ],
+      },
+    },
+  };
+
+  // Map type to a list of available unary operators.
+  static const Map<DartType, Set<String>> _uniOps = {
+    BOOL: {'!'},
+    DOUBLE: {'-'},
+    DURATION: {'-'},
+    FLOAT32X4: {'-'},
+    FLOAT64X2: {'-'},
+    INT: {'-', '~'},
+    NUM: {'-'},
+  };
+
+  // Map type to a list of assignment operators with a set of the
+  // assignable right hand side types.
+  static const Map<DartType, Map<String, Set<DartType>>> _assignOps = {
+    BOOL: {
+      '=': {
+        BOOL,
+      },
+      '??=': {
+        BOOL,
+      },
+    },
+    DOUBLE: {
+      '=': {
+        DOUBLE,
+      },
+      '??=': {
+        DOUBLE,
+      },
+      '+=': {
+        NUM,
+      },
+      '-=': {
+        NUM,
+      },
+      '*=': {
+        NUM,
+      },
+      '%=': {
+        NUM,
+      },
+      '/=': {
+        NUM,
+      },
+    },
+    DURATION: {
+      '=': {
+        DURATION,
+      },
+      '??=': {
+        DURATION,
+      },
+      '+=': {
+        DURATION,
+      },
+      '-=': {
+        DURATION,
+      },
+      '*=': {
+        NUM,
+      },
+      '~/=': {
+        INT,
+      },
+    },
+    FLOAT32LIST: {
+      '=': {
+        FLOAT32LIST,
+      },
+      '??=': {
+        FLOAT32LIST,
+      },
+    },
+    FLOAT32X4: {
+      '=': {
+        FLOAT32X4,
+      },
+      '??=': {
+        FLOAT32X4,
+      },
+      '+=': {
+        FLOAT32X4,
+      },
+      '-=': {
+        FLOAT32X4,
+      },
+      '*=': {
+        FLOAT32X4,
+      },
+      '/=': {
+        FLOAT32X4,
+      },
+    },
+    FLOAT32X4LIST: {
+      '=': {
+        FLOAT32X4LIST,
+      },
+      '??=': {
+        FLOAT32X4LIST,
+      },
+    },
+    FLOAT64LIST: {
+      '=': {
+        FLOAT64LIST,
+      },
+      '??=': {
+        FLOAT64LIST,
+      },
+    },
+    FLOAT64X2: {
+      '=': {
+        FLOAT64X2,
+      },
+      '??=': {
+        FLOAT64X2,
+      },
+      '+=': {
+        FLOAT64X2,
+      },
+      '-=': {
+        FLOAT64X2,
+      },
+      '*=': {
+        FLOAT64X2,
+      },
+      '/=': {
+        FLOAT64X2,
+      },
+    },
+    FLOAT64X2LIST: {
+      '=': {
+        FLOAT64X2LIST,
+      },
+      '??=': {
+        FLOAT64X2LIST,
+      },
+    },
+    INT: {
+      '~/=': {
+        NUM,
+      },
+      '=': {
+        INT,
+      },
+      '??=': {
+        INT,
+      },
+      '&=': {
+        INT,
+      },
+      '|=': {
+        INT,
+      },
+      '^=': {
+        INT,
+      },
+      '<<=': {
+        INT,
+      },
+      '>>=': {
+        INT,
+      },
+    },
+    INT16LIST: {
+      '=': {
+        INT16LIST,
+      },
+      '??=': {
+        INT16LIST,
+      },
+    },
+    INT32LIST: {
+      '=': {
+        INT32LIST,
+      },
+      '??=': {
+        INT32LIST,
+      },
+    },
+    INT32X4: {
+      '=': {
+        INT32X4,
+      },
+      '??=': {
+        INT32X4,
+      },
+      '|=': {
+        INT32X4,
+      },
+      '&=': {
+        INT32X4,
+      },
+      '^=': {
+        INT32X4,
+      },
+      '+=': {
+        INT32X4,
+      },
+      '-=': {
+        INT32X4,
+      },
+    },
+    INT32X4LIST: {
+      '=': {
+        INT32X4LIST,
+      },
+      '??=': {
+        INT32X4LIST,
+      },
+    },
+    INT64LIST: {
+      '=': {
+        INT64LIST,
+      },
+      '??=': {
+        INT64LIST,
+      },
+    },
+    INT8LIST: {
+      '=': {
+        INT8LIST,
+      },
+      '??=': {
+        INT8LIST,
+      },
+    },
+    LIST_BOOL: {
+      '=': {
+        LIST_BOOL,
+      },
+      '??=': {
+        LIST_BOOL,
+      },
+      '+=': {
+        LIST_BOOL,
+      },
+    },
+    LIST_DOUBLE: {
+      '=': {
+        LIST_DOUBLE,
+      },
+      '??=': {
+        LIST_DOUBLE,
+      },
+      '+=': {
+        LIST_DOUBLE,
+      },
+    },
+    LIST_FLOAT32X4: {
+      '+=': {
+        LIST_FLOAT32X4,
+      },
+    },
+    LIST_FLOAT64X2: {
+      '+=': {
+        LIST_FLOAT64X2,
+      },
+    },
+    LIST_INT: {
+      '+=': {
+        LIST_INT,
+      },
+      '=': {
+        LIST_INT,
+      },
+      '??=': {
+        LIST_INT,
+      },
+    },
+    LIST_INT32X4: {
+      '+=': {
+        LIST_INT32X4,
+      },
+    },
+    LIST_MAP_STRING_INT: {
+      '=': {
+        LIST_MAP_STRING_INT,
+      },
+      '??=': {
+        LIST_MAP_STRING_INT,
+      },
+      '+=': {
+        LIST_MAP_STRING_INT,
+      },
+    },
+    LIST_STRING: {
+      '=': {
+        LIST_STRING,
+      },
+      '??=': {
+        LIST_STRING,
+      },
+      '+=': {
+        LIST_STRING,
+      },
+    },
+    MAP_BOOL_BOOL: {
+      '=': {
+        MAP_BOOL_BOOL,
+      },
+      '??=': {
+        MAP_BOOL_BOOL,
+      },
+    },
+    MAP_BOOL_DOUBLE: {
+      '=': {
+        MAP_BOOL_DOUBLE,
+      },
+      '??=': {
+        MAP_BOOL_DOUBLE,
+      },
+    },
+    MAP_BOOL_INT: {
+      '=': {
+        MAP_BOOL_INT,
+      },
+      '??=': {
+        MAP_BOOL_INT,
+      },
+    },
+    MAP_BOOL_MAP_INT_INT: {
+      '=': {
+        MAP_BOOL_MAP_INT_INT,
+      },
+      '??=': {
+        MAP_BOOL_MAP_INT_INT,
+      },
+    },
+    MAP_BOOL_STRING: {
+      '=': {
+        MAP_BOOL_STRING,
+      },
+      '??=': {
+        MAP_BOOL_STRING,
+      },
+    },
+    MAP_DOUBLE_BOOL: {
+      '=': {
+        MAP_DOUBLE_BOOL,
+      },
+      '??=': {
+        MAP_DOUBLE_BOOL,
+      },
+    },
+    MAP_DOUBLE_DOUBLE: {
+      '=': {
+        MAP_DOUBLE_DOUBLE,
+      },
+      '??=': {
+        MAP_DOUBLE_DOUBLE,
+      },
+    },
+    MAP_DOUBLE_INT: {
+      '=': {
+        MAP_DOUBLE_INT,
+      },
+      '??=': {
+        MAP_DOUBLE_INT,
+      },
+    },
+    MAP_DOUBLE_MAP_INT_DOUBLE: {
+      '=': {
+        MAP_DOUBLE_MAP_INT_DOUBLE,
+      },
+      '??=': {
+        MAP_DOUBLE_MAP_INT_DOUBLE,
+      },
+    },
+    MAP_DOUBLE_STRING: {
+      '=': {
+        MAP_DOUBLE_STRING,
+      },
+      '??=': {
+        MAP_DOUBLE_STRING,
+      },
+    },
+    MAP_INT_BOOL: {
+      '=': {
+        MAP_INT_BOOL,
+      },
+      '??=': {
+        MAP_INT_BOOL,
+      },
+    },
+    MAP_INT_DOUBLE: {
+      '=': {
+        MAP_INT_DOUBLE,
+      },
+      '??=': {
+        MAP_INT_DOUBLE,
+      },
+    },
+    MAP_INT_INT: {
+      '=': {
+        MAP_INT_INT,
+      },
+      '??=': {
+        MAP_INT_INT,
+      },
+    },
+    MAP_INT_MAP_DOUBLE_STRING: {
+      '=': {
+        MAP_INT_MAP_DOUBLE_STRING,
+      },
+      '??=': {
+        MAP_INT_MAP_DOUBLE_STRING,
+      },
+    },
+    MAP_INT_STRING: {
+      '=': {
+        MAP_INT_STRING,
+      },
+      '??=': {
+        MAP_INT_STRING,
+      },
+    },
+    MAP_LIST_BOOL_MAP_BOOL_STRING: {
+      '=': {
+        MAP_LIST_BOOL_MAP_BOOL_STRING,
+      },
+      '??=': {
+        MAP_LIST_BOOL_MAP_BOOL_STRING,
+      },
+    },
+    MAP_LIST_DOUBLE_MAP_BOOL_INT: {
+      '=': {
+        MAP_LIST_DOUBLE_MAP_BOOL_INT,
+      },
+      '??=': {
+        MAP_LIST_DOUBLE_MAP_BOOL_INT,
+      },
+    },
+    MAP_LIST_INT_MAP_BOOL_BOOL: {
+      '=': {
+        MAP_LIST_INT_MAP_BOOL_BOOL,
+      },
+      '??=': {
+        MAP_LIST_INT_MAP_BOOL_BOOL,
+      },
+    },
+    MAP_LIST_STRING_SET_INT: {
+      '=': {
+        MAP_LIST_STRING_SET_INT,
+      },
+      '??=': {
+        MAP_LIST_STRING_SET_INT,
+      },
+    },
+    MAP_MAP_BOOL_BOOL_DOUBLE: {
+      '=': {
+        MAP_MAP_BOOL_BOOL_DOUBLE,
+      },
+      '??=': {
+        MAP_MAP_BOOL_BOOL_DOUBLE,
+      },
+    },
+    MAP_MAP_BOOL_DOUBLE_BOOL: {
+      '=': {
+        MAP_MAP_BOOL_DOUBLE_BOOL,
+      },
+      '??=': {
+        MAP_MAP_BOOL_DOUBLE_BOOL,
+      },
+    },
+    MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT: {
+      '=': {
+        MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+      },
+      '??=': {
+        MAP_MAP_BOOL_DOUBLE_MAP_STRING_INT,
+      },
+    },
+    MAP_MAP_BOOL_INT_MAP_STRING_BOOL: {
+      '=': {
+        MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      },
+      '??=': {
+        MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      },
+    },
+    MAP_MAP_BOOL_STRING_MAP_INT_INT: {
+      '=': {
+        MAP_MAP_BOOL_STRING_MAP_INT_INT,
+      },
+      '??=': {
+        MAP_MAP_BOOL_STRING_MAP_INT_INT,
+      },
+    },
+    MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE: {
+      '=': {
+        MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+      },
+      '??=': {
+        MAP_MAP_DOUBLE_BOOL_MAP_INT_DOUBLE,
+      },
+    },
+    MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING: {
+      '=': {
+        MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+      },
+      '??=': {
+        MAP_MAP_DOUBLE_DOUBLE_MAP_DOUBLE_STRING,
+      },
+    },
+    MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE: {
+      '=': {
+        MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+      },
+      '??=': {
+        MAP_MAP_DOUBLE_INT_MAP_DOUBLE_DOUBLE,
+      },
+    },
+    MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING: {
+      '=': {
+        MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+      },
+      '??=': {
+        MAP_MAP_DOUBLE_STRING_MAP_BOOL_STRING,
+      },
+    },
+    MAP_MAP_INT_BOOL_MAP_BOOL_INT: {
+      '=': {
+        MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+      },
+      '??=': {
+        MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+      },
+    },
+    MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL: {
+      '=': {
+        MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+      },
+      '??=': {
+        MAP_MAP_INT_DOUBLE_MAP_BOOL_BOOL,
+      },
+    },
+    MAP_MAP_INT_INT_SET_INT: {
+      '=': {
+        MAP_MAP_INT_INT_SET_INT,
+      },
+      '??=': {
+        MAP_MAP_INT_INT_SET_INT,
+      },
+    },
+    MAP_MAP_INT_STRING_SET_BOOL: {
+      '=': {
+        MAP_MAP_INT_STRING_SET_BOOL,
+      },
+      '??=': {
+        MAP_MAP_INT_STRING_SET_BOOL,
+      },
+    },
+    MAP_MAP_STRING_BOOL_LIST_STRING: {
+      '=': {
+        MAP_MAP_STRING_BOOL_LIST_STRING,
+      },
+      '??=': {
+        MAP_MAP_STRING_BOOL_LIST_STRING,
+      },
+    },
+    MAP_MAP_STRING_DOUBLE_LIST_DOUBLE: {
+      '=': {
+        MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+      },
+      '??=': {
+        MAP_MAP_STRING_DOUBLE_LIST_DOUBLE,
+      },
+    },
+    MAP_MAP_STRING_INT_STRING: {
+      '=': {
+        MAP_MAP_STRING_INT_STRING,
+      },
+      '??=': {
+        MAP_MAP_STRING_INT_STRING,
+      },
+    },
+    MAP_MAP_STRING_STRING_DOUBLE: {
+      '=': {
+        MAP_MAP_STRING_STRING_DOUBLE,
+      },
+      '??=': {
+        MAP_MAP_STRING_STRING_DOUBLE,
+      },
+    },
+    MAP_SET_BOOL_SET_BOOL: {
+      '=': {
+        MAP_SET_BOOL_SET_BOOL,
+      },
+      '??=': {
+        MAP_SET_BOOL_SET_BOOL,
+      },
+    },
+    MAP_SET_DOUBLE_LIST_STRING: {
+      '=': {
+        MAP_SET_DOUBLE_LIST_STRING,
+      },
+      '??=': {
+        MAP_SET_DOUBLE_LIST_STRING,
+      },
+    },
+    MAP_SET_INT_LIST_DOUBLE: {
+      '=': {
+        MAP_SET_INT_LIST_DOUBLE,
+      },
+      '??=': {
+        MAP_SET_INT_LIST_DOUBLE,
+      },
+    },
+    MAP_SET_STRING_STRING: {
+      '=': {
+        MAP_SET_STRING_STRING,
+      },
+      '??=': {
+        MAP_SET_STRING_STRING,
+      },
+    },
+    MAP_STRING_BOOL: {
+      '=': {
+        MAP_STRING_BOOL,
+      },
+      '??=': {
+        MAP_STRING_BOOL,
+      },
+    },
+    MAP_STRING_DOUBLE: {
+      '=': {
+        MAP_STRING_DOUBLE,
+      },
+      '??=': {
+        MAP_STRING_DOUBLE,
+      },
+    },
+    MAP_STRING_INT: {
+      '=': {
+        MAP_STRING_INT,
+      },
+      '??=': {
+        MAP_STRING_INT,
+      },
+    },
+    MAP_STRING_MAP_DOUBLE_DOUBLE: {
+      '=': {
+        MAP_STRING_MAP_DOUBLE_DOUBLE,
+      },
+      '??=': {
+        MAP_STRING_MAP_DOUBLE_DOUBLE,
+      },
+    },
+    MAP_STRING_STRING: {
+      '=': {
+        MAP_STRING_STRING,
+      },
+      '??=': {
+        MAP_STRING_STRING,
+      },
+    },
+    NUM: {
+      '=': {
+        NUM,
+      },
+      '??=': {
+        NUM,
+      },
+      '+=': {
+        NUM,
+      },
+      '-=': {
+        NUM,
+      },
+      '*=': {
+        NUM,
+      },
+      '%=': {
+        NUM,
+      },
+    },
+    SET_BOOL: {
+      '=': {
+        SET_BOOL,
+      },
+      '??=': {
+        SET_BOOL,
+      },
+    },
+    SET_DOUBLE: {
+      '=': {
+        SET_DOUBLE,
+      },
+      '??=': {
+        SET_DOUBLE,
+      },
+    },
+    SET_INT: {
+      '=': {
+        SET_INT,
+      },
+      '??=': {
+        SET_INT,
+      },
+    },
+    SET_MAP_STRING_BOOL: {
+      '=': {
+        SET_MAP_STRING_BOOL,
+      },
+      '??=': {
+        SET_MAP_STRING_BOOL,
+      },
+    },
+    SET_STRING: {
+      '=': {
+        SET_STRING,
+      },
+      '??=': {
+        SET_STRING,
+      },
+    },
+    STRING: {
+      '=': {
+        STRING,
+      },
+      '??=': {
+        STRING,
+      },
+      '+=': {
+        STRING,
+      },
+      '*=': {
+        INT,
+      },
+    },
+    UINT16LIST: {
+      '=': {
+        UINT16LIST,
+      },
+      '??=': {
+        UINT16LIST,
+      },
+    },
+    UINT32LIST: {
+      '=': {
+        UINT32LIST,
+      },
+      '??=': {
+        UINT32LIST,
+      },
+    },
+    UINT64LIST: {
+      '=': {
+        UINT64LIST,
+      },
+      '??=': {
+        UINT64LIST,
+      },
+    },
+    UINT8CLAMPEDLIST: {
+      '=': {
+        UINT8CLAMPEDLIST,
+      },
+      '??=': {
+        UINT8CLAMPEDLIST,
+      },
+    },
+    UINT8LIST: {
+      '=': {
+        UINT8LIST,
+      },
+      '??=': {
+        UINT8LIST,
+      },
+    },
+  };
+}
+
+class DartTypeNoFp extends DartType {
+  final String name;
+  const DartTypeNoFp._withName(this.name) : super._withName(name);
+  const DartTypeNoFp() : name = null;
+  static bool isListType(DartType tp) {
+    return DartType._listTypes.contains(tp);
+  }
+
+  static bool isMapType(DartType tp) {
+    return DartType._mapTypes.contains(tp);
+  }
+
+  static bool isCollectionType(DartType tp) {
+    return DartType._collectionTypes.contains(tp);
+  }
+
+  static bool isGrowableType(DartType tp) {
+    return DartType._growableTypes.contains(tp);
+  }
+
+  static bool isComplexType(DartType tp) {
+    return DartType._complexTypes.contains(tp);
+  }
+
+  bool isInterfaceOfType(DartType tp, DartType iTp) {
+    return _interfaceRels.containsKey(iTp) && _interfaceRels[iTp].contains(tp);
+  }
+
+  Set<DartType> get mapTypes {
+    return _mapTypes;
+  }
+
+  bool isSpecializable(DartType tp) {
+    return _interfaceRels.containsKey(tp);
+  }
+
+  Set<DartType> interfaces(DartType tp) {
+    if (_interfaceRels.containsKey(tp)) {
+      return _interfaceRels[tp];
+    }
+    return null;
+  }
+
+  DartType indexType(DartType tp) {
+    if (_indexedBy.containsKey(tp)) {
+      return _indexedBy[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> indexableElementTypes(DartType tp) {
+    if (_indexableElementOf.containsKey(tp)) {
+      return _indexableElementOf[tp];
+    }
+    return null;
+  }
+
+  bool isIndexableElementType(DartType tp) {
+    return _indexableElementOf.containsKey(tp);
+  }
+
+  DartType elementType(DartType tp) {
+    if (_subscriptsTo.containsKey(tp)) {
+      return _subscriptsTo[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> get iterableTypes1 {
+    return _iterableTypes1;
+  }
+
+  Set<String> uniOps(DartType tp) {
+    if (_uniOps.containsKey(tp)) {
+      return _uniOps[tp];
+    }
+    return <String>{};
+  }
+
+  Set<String> binOps(DartType tp) {
+    if (_binOps.containsKey(tp)) {
+      return _binOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<List<DartType>> binOpParameters(DartType tp, String op) {
+    if (_binOps.containsKey(tp) && _binOps[tp].containsKey(op)) {
+      return _binOps[tp][op];
+    }
+    return null;
+  }
+
+  Set<String> assignOps(DartType tp) {
+    if (_assignOps.containsKey(tp)) {
+      return _assignOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<DartType> assignOpRhs(DartType tp, String op) {
+    if (_assignOps.containsKey(tp) && _assignOps[tp].containsKey(op)) {
+      return _assignOps[tp][op];
+    }
+    return <DartType>{};
+  }
+
+  bool hasConstructor(DartType tp) {
+    return _constructors.containsKey(tp);
+  }
+
+  Set<String> constructors(DartType tp) {
+    if (_constructors.containsKey(tp)) {
+      return _constructors[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  List<DartType> constructorParameters(DartType tp, String constructor) {
+    if (_constructors.containsKey(tp) &&
+        _constructors[tp].containsKey(constructor)) {
+      return _constructors[tp][constructor];
+    }
+    return null;
+  }
+
+  Set<DartType> get allTypes {
+    return _allTypes;
+  }
+
+  // All types extracted from analyzer.
+  static const _allTypes = {
+    DartType.INT8LIST,
+    DartType.UINT8LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.INT16LIST,
+    DartType.UINT16LIST,
+    DartType.INT32LIST,
+    DartType.UINT32LIST,
+    DartType.INT64LIST,
+    DartType.UINT64LIST,
+    DartType.INT32X4LIST,
+    DartType.INT32X4,
+    DartType.BOOL,
+    DartType.DURATION,
+    DartType.INT,
+    DartType.NUM,
+    DartType.STRING,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.LIST_MAP_STRING_INT,
+    DartType.SET_MAP_STRING_BOOL,
+    DartType.MAP_BOOL_MAP_INT_INT,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    DartType.MAP_LIST_STRING_SET_INT,
+    DartType.MAP_SET_BOOL_SET_BOOL,
+    DartType.MAP_SET_STRING_STRING,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    DartType.MAP_MAP_INT_INT_SET_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    DartType.MAP_MAP_STRING_INT_STRING,
+  };
+
+  // All List<E> types: LIST_INT, LIST_STRING, etc.
+  static const Set<DartType> _listTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_MAP_STRING_INT,
+    DartType.LIST_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All Set types: SET_INT, SET_STRING, etc.
+  static const Set<DartType> _setTypes = {
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_MAP_STRING_BOOL,
+    DartType.SET_STRING,
+  };
+
+  // All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
+  static const Set<DartType> _mapTypes = {
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_MAP_INT_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    DartType.MAP_LIST_STRING_SET_INT,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    DartType.MAP_MAP_INT_INT_SET_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    DartType.MAP_MAP_STRING_INT_STRING,
+    DartType.MAP_SET_BOOL_SET_BOOL,
+    DartType.MAP_SET_STRING_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+  };
+
+  // All collection types: list, map and set types.
+  static const Set<DartType> _collectionTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_MAP_STRING_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_MAP_INT_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    DartType.MAP_LIST_STRING_SET_INT,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    DartType.MAP_MAP_INT_INT_SET_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    DartType.MAP_MAP_STRING_INT_STRING,
+    DartType.MAP_SET_BOOL_SET_BOOL,
+    DartType.MAP_SET_STRING_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_MAP_STRING_BOOL,
+    DartType.SET_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All growable types: list, map, set and string types.
+  static const Set<DartType> _growableTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_MAP_STRING_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_MAP_INT_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    DartType.MAP_LIST_STRING_SET_INT,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    DartType.MAP_MAP_INT_INT_SET_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    DartType.MAP_MAP_STRING_INT_STRING,
+    DartType.MAP_SET_BOOL_SET_BOOL,
+    DartType.MAP_SET_STRING_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_MAP_STRING_BOOL,
+    DartType.SET_STRING,
+    DartType.STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All trivially indexable types: Map types and List types.
+  // Elements of these can be written and read by [], unlike Set
+  // which uses getElementAt to access individual elements.
+  static const Set<DartType> _indexableTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_MAP_STRING_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_MAP_INT_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    DartType.MAP_LIST_STRING_SET_INT,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    DartType.MAP_MAP_INT_INT_SET_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    DartType.MAP_MAP_STRING_INT_STRING,
+    DartType.MAP_SET_BOOL_SET_BOOL,
+    DartType.MAP_SET_STRING_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // Map type to the resulting type when subscripted.
+  // Example: List<String> subscripts to String.
+  static const Map<DartType, DartType> _subscriptsTo = {
+    DartType.DURATION: DartType.DURATION,
+    DartType.INT16LIST: DartType.INT,
+    DartType.INT32LIST: DartType.INT,
+    DartType.INT32X4LIST: DartType.INT32X4,
+    DartType.INT64LIST: DartType.INT,
+    DartType.INT8LIST: DartType.INT,
+    DartType.LIST_BOOL: DartType.BOOL,
+    DartType.LIST_INT: DartType.INT,
+    DartType.LIST_MAP_STRING_INT: DartType.MAP_STRING_INT,
+    DartType.LIST_STRING: DartType.STRING,
+    DartType.MAP_BOOL_BOOL: DartType.BOOL,
+    DartType.MAP_BOOL_INT: DartType.INT,
+    DartType.MAP_BOOL_MAP_INT_INT: DartType.MAP_INT_INT,
+    DartType.MAP_BOOL_STRING: DartType.STRING,
+    DartType.MAP_INT_BOOL: DartType.BOOL,
+    DartType.MAP_INT_INT: DartType.INT,
+    DartType.MAP_INT_STRING: DartType.STRING,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING: DartType.MAP_BOOL_STRING,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL: DartType.MAP_BOOL_BOOL,
+    DartType.MAP_LIST_STRING_SET_INT: DartType.SET_INT,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL: DartType.MAP_STRING_BOOL,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT: DartType.MAP_INT_INT,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT: DartType.MAP_BOOL_INT,
+    DartType.MAP_MAP_INT_INT_SET_INT: DartType.SET_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL: DartType.SET_BOOL,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING: DartType.LIST_STRING,
+    DartType.MAP_MAP_STRING_INT_STRING: DartType.STRING,
+    DartType.MAP_SET_BOOL_SET_BOOL: DartType.SET_BOOL,
+    DartType.MAP_SET_STRING_STRING: DartType.STRING,
+    DartType.MAP_STRING_BOOL: DartType.BOOL,
+    DartType.MAP_STRING_INT: DartType.INT,
+    DartType.MAP_STRING_STRING: DartType.STRING,
+    DartType.NUM: DartType.NUM,
+    DartType.SET_BOOL: DartType.BOOL,
+    DartType.SET_INT: DartType.INT,
+    DartType.SET_MAP_STRING_BOOL: DartType.MAP_STRING_BOOL,
+    DartType.SET_STRING: DartType.STRING,
+    DartType.STRING: DartType.STRING,
+    DartType.UINT16LIST: DartType.INT,
+    DartType.UINT32LIST: DartType.INT,
+    DartType.UINT64LIST: DartType.INT,
+    DartType.UINT8CLAMPEDLIST: DartType.INT,
+    DartType.UINT8LIST: DartType.INT,
+  };
+
+  // Map type to type required as index.
+  // Example: List<String> is indexed by int,
+  // Map<String, double> indexed by String.
+  static const Map<DartType, DartType> _indexedBy = {
+    DartType.INT16LIST: DartType.INT,
+    DartType.INT32LIST: DartType.INT,
+    DartType.INT32X4LIST: DartType.INT,
+    DartType.INT64LIST: DartType.INT,
+    DartType.INT8LIST: DartType.INT,
+    DartType.LIST_BOOL: DartType.INT,
+    DartType.LIST_INT: DartType.INT,
+    DartType.LIST_MAP_STRING_INT: DartType.INT,
+    DartType.LIST_STRING: DartType.INT,
+    DartType.MAP_BOOL_BOOL: DartType.BOOL,
+    DartType.MAP_BOOL_INT: DartType.BOOL,
+    DartType.MAP_BOOL_MAP_INT_INT: DartType.BOOL,
+    DartType.MAP_BOOL_STRING: DartType.BOOL,
+    DartType.MAP_INT_BOOL: DartType.INT,
+    DartType.MAP_INT_INT: DartType.INT,
+    DartType.MAP_INT_STRING: DartType.INT,
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING: DartType.LIST_BOOL,
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL: DartType.LIST_INT,
+    DartType.MAP_LIST_STRING_SET_INT: DartType.LIST_STRING,
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL: DartType.MAP_BOOL_INT,
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT: DartType.MAP_BOOL_STRING,
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT: DartType.MAP_INT_BOOL,
+    DartType.MAP_MAP_INT_INT_SET_INT: DartType.MAP_INT_INT,
+    DartType.MAP_MAP_INT_STRING_SET_BOOL: DartType.MAP_INT_STRING,
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING: DartType.MAP_STRING_BOOL,
+    DartType.MAP_MAP_STRING_INT_STRING: DartType.MAP_STRING_INT,
+    DartType.MAP_SET_BOOL_SET_BOOL: DartType.SET_BOOL,
+    DartType.MAP_SET_STRING_STRING: DartType.SET_STRING,
+    DartType.MAP_STRING_BOOL: DartType.STRING,
+    DartType.MAP_STRING_INT: DartType.STRING,
+    DartType.MAP_STRING_STRING: DartType.STRING,
+    DartType.UINT16LIST: DartType.INT,
+    DartType.UINT32LIST: DartType.INT,
+    DartType.UINT64LIST: DartType.INT,
+    DartType.UINT8CLAMPEDLIST: DartType.INT,
+    DartType.UINT8LIST: DartType.INT,
+  };
+
+  // Map type to a Set of types that contain it as an element.
+  // Example: String is element of List<String> and Map<int, String>
+  static const Map<DartType, Set<DartType>> _elementOf = {
+    DartType.BOOL: {
+      DartType.LIST_BOOL,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_STRING_BOOL,
+      DartType.SET_BOOL,
+    },
+    DartType.DURATION: {
+      DartType.DURATION,
+    },
+    DartType.INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_INT_INT,
+      DartType.MAP_STRING_INT,
+      DartType.SET_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.LIST_STRING: {
+      DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    },
+    DartType.MAP_BOOL_BOOL: {
+      DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    },
+    DartType.MAP_BOOL_INT: {
+      DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    },
+    DartType.MAP_BOOL_STRING: {
+      DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    },
+    DartType.MAP_INT_INT: {
+      DartType.MAP_BOOL_MAP_INT_INT,
+      DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    },
+    DartType.MAP_STRING_BOOL: {
+      DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      DartType.SET_MAP_STRING_BOOL,
+    },
+    DartType.MAP_STRING_INT: {
+      DartType.LIST_MAP_STRING_INT,
+    },
+    DartType.NUM: {
+      DartType.NUM,
+    },
+    DartType.SET_BOOL: {
+      DartType.MAP_MAP_INT_STRING_SET_BOOL,
+      DartType.MAP_SET_BOOL_SET_BOOL,
+    },
+    DartType.SET_INT: {
+      DartType.MAP_LIST_STRING_SET_INT,
+      DartType.MAP_MAP_INT_INT_SET_INT,
+    },
+    DartType.STRING: {
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_MAP_STRING_INT_STRING,
+      DartType.MAP_SET_STRING_STRING,
+      DartType.MAP_STRING_STRING,
+      DartType.SET_STRING,
+      DartType.STRING,
+    },
+  };
+
+  // Map type to a Set of types that contain it as an indexable element.
+  // Same as element of, but without Set types.
+  static const Map<DartType, Set<DartType>> _indexableElementOf = {
+    DartType.BOOL: {
+      DartType.LIST_BOOL,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_STRING_BOOL,
+    },
+    DartType.INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_INT_INT,
+      DartType.MAP_STRING_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.LIST_STRING: {
+      DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+    },
+    DartType.MAP_BOOL_BOOL: {
+      DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+    },
+    DartType.MAP_BOOL_INT: {
+      DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+    },
+    DartType.MAP_BOOL_STRING: {
+      DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+    },
+    DartType.MAP_INT_INT: {
+      DartType.MAP_BOOL_MAP_INT_INT,
+      DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+    },
+    DartType.MAP_STRING_BOOL: {
+      DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+    },
+    DartType.MAP_STRING_INT: {
+      DartType.LIST_MAP_STRING_INT,
+    },
+    DartType.SET_BOOL: {
+      DartType.MAP_MAP_INT_STRING_SET_BOOL,
+      DartType.MAP_SET_BOOL_SET_BOOL,
+    },
+    DartType.SET_INT: {
+      DartType.MAP_LIST_STRING_SET_INT,
+      DartType.MAP_MAP_INT_INT_SET_INT,
+    },
+    DartType.STRING: {
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_MAP_STRING_INT_STRING,
+      DartType.MAP_SET_STRING_STRING,
+      DartType.MAP_STRING_STRING,
+    },
+  };
+
+  // All iterable types: Set types + List types.
+  // These can be used in for(x in <iterable type>),
+  // therefore Map is not included.
+  static const Set<DartType> _iterableTypes1 = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_MAP_STRING_INT,
+    DartType.LIST_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // Map Interface type to Set of types that implement it.
+  // Example: interface num is implemented by int and double.
+  static const Map<DartType, Set<DartType>> _interfaceRels = {
+    DartType.COMPARABLE_DURATION: {
+      DartType.DURATION,
+    },
+    DartType.COMPARABLE_NUM: {
+      DartType.INT,
+      DartType.NUM,
+    },
+    DartType.COMPARABLE_STRING: {
+      DartType.STRING,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_BOOL: {
+      DartType.LIST_BOOL,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_E: {
+      DartType.LIST_BOOL,
+      DartType.LIST_INT,
+      DartType.LIST_MAP_STRING_INT,
+      DartType.LIST_STRING,
+      DartType.SET_BOOL,
+      DartType.SET_INT,
+      DartType.SET_MAP_STRING_BOOL,
+      DartType.SET_STRING,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_MAP_STRING_INT: {
+      DartType.LIST_MAP_STRING_INT,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_STRING: {
+      DartType.LIST_STRING,
+    },
+    DartType.ITERABLE_E: {
+      DartType.LIST_BOOL,
+      DartType.LIST_INT,
+      DartType.LIST_MAP_STRING_INT,
+      DartType.LIST_STRING,
+      DartType.SET_BOOL,
+      DartType.SET_INT,
+      DartType.SET_MAP_STRING_BOOL,
+      DartType.SET_STRING,
+    },
+    DartType.ITERABLE_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.ITERABLE_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.LIST_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.LIST_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.NUM: {
+      DartType.INT,
+      DartType.NUM,
+    },
+    DartType.OBJECT: {
+      DartType.BOOL,
+      DartType.DURATION,
+      DartType.INT,
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT32X4,
+      DartType.INT32X4LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_BOOL,
+      DartType.LIST_INT,
+      DartType.LIST_MAP_STRING_INT,
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_BOOL_MAP_INT_INT,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_INT_INT,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+      DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+      DartType.MAP_LIST_STRING_SET_INT,
+      DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+      DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+      DartType.MAP_MAP_INT_INT_SET_INT,
+      DartType.MAP_MAP_INT_STRING_SET_BOOL,
+      DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+      DartType.MAP_MAP_STRING_INT_STRING,
+      DartType.MAP_SET_BOOL_SET_BOOL,
+      DartType.MAP_SET_STRING_STRING,
+      DartType.MAP_STRING_BOOL,
+      DartType.MAP_STRING_INT,
+      DartType.MAP_STRING_STRING,
+      DartType.NUM,
+      DartType.SET_BOOL,
+      DartType.SET_INT,
+      DartType.SET_MAP_STRING_BOOL,
+      DartType.SET_STRING,
+      DartType.STRING,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.PATTERN: {
+      DartType.STRING,
+    },
+    DartType.TYPEDDATA: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT32X4LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType._TYPEDINTLIST: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+  };
+
+  // Map type to a list of constructors names with a list of constructor
+  // parameter types.
+  static const Map<DartType, Map<String, List<DartType>>> _constructors = {
+    DartType.DURATION: {
+      '': [],
+    },
+    DartType.INT16LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT32X4: {
+      '': [
+        DartType.INT,
+        DartType.INT,
+        DartType.INT,
+        DartType.INT,
+      ],
+    },
+    DartType.INT32X4LIST: {
+      '': [
+        DartType.INT,
+      ],
+    },
+    DartType.INT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT8LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT16LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT8CLAMPEDLIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT8LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+  };
+
+  // Map type to a list of binary operators with set of the respective
+  // types for the first and second operand.
+  static const Map<DartType, Map<String, Set<List<DartType>>>> _binOps = {
+    DartType.BOOL: {
+      '&': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '&&': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '<': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '<=': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '==': {
+        [
+          DartType.NUM,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.STRING,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_BOOL,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_INT,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_STRING,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_MAP_STRING_INT,
+          DartType.OBJECT,
+        ],
+      },
+      '>': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '>=': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '^': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '|': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '||': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+    },
+    DartType.DURATION: {
+      '*': {
+        [
+          DartType.DURATION,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '-': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '??': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '~/': {
+        [
+          DartType.DURATION,
+          DartType.INT,
+        ],
+      },
+    },
+    DartType.INT: {
+      '&': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '<<': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '>>': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '^': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '|': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '~/': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+    },
+    DartType.INT32X4: {
+      '&': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '+': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '-': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '^': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '|': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+    },
+    DartType.LIST_BOOL: {
+      '+': {
+        [
+          DartType.LIST_BOOL,
+          DartType.LIST_BOOL,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_BOOL,
+          DartType.LIST_BOOL,
+        ],
+      },
+    },
+    DartType.LIST_FLOAT32X4: {
+      '??': {
+        [
+          DartType.LIST_FLOAT32X4,
+          DartType.LIST_FLOAT32X4,
+        ],
+      },
+    },
+    DartType.LIST_FLOAT64X2: {
+      '??': {
+        [
+          DartType.LIST_FLOAT64X2,
+          DartType.LIST_FLOAT64X2,
+        ],
+      },
+    },
+    DartType.LIST_INT: {
+      '+': {
+        [
+          DartType.LIST_INT,
+          DartType.LIST_INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_INT,
+          DartType.LIST_INT,
+        ],
+      },
+    },
+    DartType.LIST_INT32X4: {
+      '+': {
+        [
+          DartType.INT32X4LIST,
+          DartType.LIST_INT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_INT32X4,
+          DartType.LIST_INT32X4,
+        ],
+      },
+    },
+    DartType.LIST_MAP_STRING_INT: {
+      '+': {
+        [
+          DartType.LIST_MAP_STRING_INT,
+          DartType.LIST_MAP_STRING_INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_MAP_STRING_INT,
+          DartType.LIST_MAP_STRING_INT,
+        ],
+      },
+    },
+    DartType.LIST_STRING: {
+      '+': {
+        [
+          DartType.LIST_STRING,
+          DartType.LIST_STRING,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_STRING,
+          DartType.LIST_STRING,
+        ],
+      },
+    },
+    DartType.NUM: {
+      '%': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '*': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '-': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+    },
+    DartType.STRING: {
+      '*': {
+        [
+          DartType.STRING,
+          DartType.INT,
+        ],
+      },
+      '+': {
+        [
+          DartType.STRING,
+          DartType.STRING,
+        ],
+      },
+      '??': {
+        [
+          DartType.STRING,
+          DartType.STRING,
+        ],
+      },
+    },
+  };
+
+  // Map type to a list of available unary operators.
+  static const Map<DartType, Set<String>> _uniOps = {
+    DartType.BOOL: {'!'},
+    DartType.DURATION: {'-'},
+    DartType.INT: {'-', '~'},
+    DartType.NUM: {'-'},
+  };
+
+  // Map type to a list of assignment operators with a set of the
+  // assignable right hand side types.
+  static const Map<DartType, Map<String, Set<DartType>>> _assignOps = {
+    DartType.BOOL: {
+      '=': {
+        DartType.BOOL,
+      },
+      '??=': {
+        DartType.BOOL,
+      },
+    },
+    DartType.DURATION: {
+      '=': {
+        DartType.DURATION,
+      },
+      '??=': {
+        DartType.DURATION,
+      },
+      '+=': {
+        DartType.DURATION,
+      },
+      '-=': {
+        DartType.DURATION,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '~/=': {
+        DartType.INT,
+      },
+    },
+    DartType.INT: {
+      '~/=': {
+        DartType.NUM,
+      },
+      '=': {
+        DartType.INT,
+      },
+      '??=': {
+        DartType.INT,
+      },
+      '&=': {
+        DartType.INT,
+      },
+      '|=': {
+        DartType.INT,
+      },
+      '^=': {
+        DartType.INT,
+      },
+      '<<=': {
+        DartType.INT,
+      },
+      '>>=': {
+        DartType.INT,
+      },
+    },
+    DartType.INT16LIST: {
+      '=': {
+        DartType.INT16LIST,
+      },
+      '??=': {
+        DartType.INT16LIST,
+      },
+    },
+    DartType.INT32LIST: {
+      '=': {
+        DartType.INT32LIST,
+      },
+      '??=': {
+        DartType.INT32LIST,
+      },
+    },
+    DartType.INT32X4: {
+      '=': {
+        DartType.INT32X4,
+      },
+      '??=': {
+        DartType.INT32X4,
+      },
+      '|=': {
+        DartType.INT32X4,
+      },
+      '&=': {
+        DartType.INT32X4,
+      },
+      '^=': {
+        DartType.INT32X4,
+      },
+      '+=': {
+        DartType.INT32X4,
+      },
+      '-=': {
+        DartType.INT32X4,
+      },
+    },
+    DartType.INT32X4LIST: {
+      '=': {
+        DartType.INT32X4LIST,
+      },
+      '??=': {
+        DartType.INT32X4LIST,
+      },
+    },
+    DartType.INT64LIST: {
+      '=': {
+        DartType.INT64LIST,
+      },
+      '??=': {
+        DartType.INT64LIST,
+      },
+    },
+    DartType.INT8LIST: {
+      '=': {
+        DartType.INT8LIST,
+      },
+      '??=': {
+        DartType.INT8LIST,
+      },
+    },
+    DartType.LIST_BOOL: {
+      '=': {
+        DartType.LIST_BOOL,
+      },
+      '??=': {
+        DartType.LIST_BOOL,
+      },
+      '+=': {
+        DartType.LIST_BOOL,
+      },
+    },
+    DartType.LIST_FLOAT32X4: {
+      '+=': {
+        DartType.LIST_FLOAT32X4,
+      },
+    },
+    DartType.LIST_FLOAT64X2: {
+      '+=': {
+        DartType.LIST_FLOAT64X2,
+      },
+    },
+    DartType.LIST_INT: {
+      '+=': {
+        DartType.LIST_INT,
+      },
+      '=': {
+        DartType.LIST_INT,
+      },
+      '??=': {
+        DartType.LIST_INT,
+      },
+    },
+    DartType.LIST_INT32X4: {
+      '+=': {
+        DartType.LIST_INT32X4,
+      },
+    },
+    DartType.LIST_MAP_STRING_INT: {
+      '=': {
+        DartType.LIST_MAP_STRING_INT,
+      },
+      '??=': {
+        DartType.LIST_MAP_STRING_INT,
+      },
+      '+=': {
+        DartType.LIST_MAP_STRING_INT,
+      },
+    },
+    DartType.LIST_STRING: {
+      '=': {
+        DartType.LIST_STRING,
+      },
+      '??=': {
+        DartType.LIST_STRING,
+      },
+      '+=': {
+        DartType.LIST_STRING,
+      },
+    },
+    DartType.MAP_BOOL_BOOL: {
+      '=': {
+        DartType.MAP_BOOL_BOOL,
+      },
+      '??=': {
+        DartType.MAP_BOOL_BOOL,
+      },
+    },
+    DartType.MAP_BOOL_INT: {
+      '=': {
+        DartType.MAP_BOOL_INT,
+      },
+      '??=': {
+        DartType.MAP_BOOL_INT,
+      },
+    },
+    DartType.MAP_BOOL_MAP_INT_INT: {
+      '=': {
+        DartType.MAP_BOOL_MAP_INT_INT,
+      },
+      '??=': {
+        DartType.MAP_BOOL_MAP_INT_INT,
+      },
+    },
+    DartType.MAP_BOOL_STRING: {
+      '=': {
+        DartType.MAP_BOOL_STRING,
+      },
+      '??=': {
+        DartType.MAP_BOOL_STRING,
+      },
+    },
+    DartType.MAP_INT_BOOL: {
+      '=': {
+        DartType.MAP_INT_BOOL,
+      },
+      '??=': {
+        DartType.MAP_INT_BOOL,
+      },
+    },
+    DartType.MAP_INT_INT: {
+      '=': {
+        DartType.MAP_INT_INT,
+      },
+      '??=': {
+        DartType.MAP_INT_INT,
+      },
+    },
+    DartType.MAP_INT_STRING: {
+      '=': {
+        DartType.MAP_INT_STRING,
+      },
+      '??=': {
+        DartType.MAP_INT_STRING,
+      },
+    },
+    DartType.MAP_LIST_BOOL_MAP_BOOL_STRING: {
+      '=': {
+        DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+      },
+      '??=': {
+        DartType.MAP_LIST_BOOL_MAP_BOOL_STRING,
+      },
+    },
+    DartType.MAP_LIST_INT_MAP_BOOL_BOOL: {
+      '=': {
+        DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+      },
+      '??=': {
+        DartType.MAP_LIST_INT_MAP_BOOL_BOOL,
+      },
+    },
+    DartType.MAP_LIST_STRING_SET_INT: {
+      '=': {
+        DartType.MAP_LIST_STRING_SET_INT,
+      },
+      '??=': {
+        DartType.MAP_LIST_STRING_SET_INT,
+      },
+    },
+    DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL: {
+      '=': {
+        DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      },
+      '??=': {
+        DartType.MAP_MAP_BOOL_INT_MAP_STRING_BOOL,
+      },
+    },
+    DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT: {
+      '=': {
+        DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+      },
+      '??=': {
+        DartType.MAP_MAP_BOOL_STRING_MAP_INT_INT,
+      },
+    },
+    DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT: {
+      '=': {
+        DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+      },
+      '??=': {
+        DartType.MAP_MAP_INT_BOOL_MAP_BOOL_INT,
+      },
+    },
+    DartType.MAP_MAP_INT_INT_SET_INT: {
+      '=': {
+        DartType.MAP_MAP_INT_INT_SET_INT,
+      },
+      '??=': {
+        DartType.MAP_MAP_INT_INT_SET_INT,
+      },
+    },
+    DartType.MAP_MAP_INT_STRING_SET_BOOL: {
+      '=': {
+        DartType.MAP_MAP_INT_STRING_SET_BOOL,
+      },
+      '??=': {
+        DartType.MAP_MAP_INT_STRING_SET_BOOL,
+      },
+    },
+    DartType.MAP_MAP_STRING_BOOL_LIST_STRING: {
+      '=': {
+        DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+      },
+      '??=': {
+        DartType.MAP_MAP_STRING_BOOL_LIST_STRING,
+      },
+    },
+    DartType.MAP_MAP_STRING_INT_STRING: {
+      '=': {
+        DartType.MAP_MAP_STRING_INT_STRING,
+      },
+      '??=': {
+        DartType.MAP_MAP_STRING_INT_STRING,
+      },
+    },
+    DartType.MAP_SET_BOOL_SET_BOOL: {
+      '=': {
+        DartType.MAP_SET_BOOL_SET_BOOL,
+      },
+      '??=': {
+        DartType.MAP_SET_BOOL_SET_BOOL,
+      },
+    },
+    DartType.MAP_SET_STRING_STRING: {
+      '=': {
+        DartType.MAP_SET_STRING_STRING,
+      },
+      '??=': {
+        DartType.MAP_SET_STRING_STRING,
+      },
+    },
+    DartType.MAP_STRING_BOOL: {
+      '=': {
+        DartType.MAP_STRING_BOOL,
+      },
+      '??=': {
+        DartType.MAP_STRING_BOOL,
+      },
+    },
+    DartType.MAP_STRING_INT: {
+      '=': {
+        DartType.MAP_STRING_INT,
+      },
+      '??=': {
+        DartType.MAP_STRING_INT,
+      },
+    },
+    DartType.MAP_STRING_STRING: {
+      '=': {
+        DartType.MAP_STRING_STRING,
+      },
+      '??=': {
+        DartType.MAP_STRING_STRING,
+      },
+    },
+    DartType.NUM: {
+      '=': {
+        DartType.NUM,
+      },
+      '??=': {
+        DartType.NUM,
+      },
+      '+=': {
+        DartType.NUM,
+      },
+      '-=': {
+        DartType.NUM,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '%=': {
+        DartType.NUM,
+      },
+    },
+    DartType.SET_BOOL: {
+      '=': {
+        DartType.SET_BOOL,
+      },
+      '??=': {
+        DartType.SET_BOOL,
+      },
+    },
+    DartType.SET_INT: {
+      '=': {
+        DartType.SET_INT,
+      },
+      '??=': {
+        DartType.SET_INT,
+      },
+    },
+    DartType.SET_MAP_STRING_BOOL: {
+      '=': {
+        DartType.SET_MAP_STRING_BOOL,
+      },
+      '??=': {
+        DartType.SET_MAP_STRING_BOOL,
+      },
+    },
+    DartType.SET_STRING: {
+      '=': {
+        DartType.SET_STRING,
+      },
+      '??=': {
+        DartType.SET_STRING,
+      },
+    },
+    DartType.STRING: {
+      '=': {
+        DartType.STRING,
+      },
+      '??=': {
+        DartType.STRING,
+      },
+      '+=': {
+        DartType.STRING,
+      },
+      '*=': {
+        DartType.INT,
+      },
+    },
+    DartType.UINT16LIST: {
+      '=': {
+        DartType.UINT16LIST,
+      },
+      '??=': {
+        DartType.UINT16LIST,
+      },
+    },
+    DartType.UINT32LIST: {
+      '=': {
+        DartType.UINT32LIST,
+      },
+      '??=': {
+        DartType.UINT32LIST,
+      },
+    },
+    DartType.UINT64LIST: {
+      '=': {
+        DartType.UINT64LIST,
+      },
+      '??=': {
+        DartType.UINT64LIST,
+      },
+    },
+    DartType.UINT8CLAMPEDLIST: {
+      '=': {
+        DartType.UINT8CLAMPEDLIST,
+      },
+      '??=': {
+        DartType.UINT8CLAMPEDLIST,
+      },
+    },
+    DartType.UINT8LIST: {
+      '=': {
+        DartType.UINT8LIST,
+      },
+      '??=': {
+        DartType.UINT8LIST,
+      },
+    },
+  };
+}
+
+class DartTypeFlatTp extends DartType {
+  final String name;
+  const DartTypeFlatTp._withName(this.name) : super._withName(name);
+  const DartTypeFlatTp() : name = null;
+  static bool isListType(DartType tp) {
+    return DartType._listTypes.contains(tp);
+  }
+
+  static bool isMapType(DartType tp) {
+    return DartType._mapTypes.contains(tp);
+  }
+
+  static bool isCollectionType(DartType tp) {
+    return DartType._collectionTypes.contains(tp);
+  }
+
+  static bool isGrowableType(DartType tp) {
+    return DartType._growableTypes.contains(tp);
+  }
+
+  static bool isComplexType(DartType tp) {
+    return DartType._complexTypes.contains(tp);
+  }
+
+  bool isInterfaceOfType(DartType tp, DartType iTp) {
+    return _interfaceRels.containsKey(iTp) && _interfaceRels[iTp].contains(tp);
+  }
+
+  Set<DartType> get mapTypes {
+    return _mapTypes;
+  }
+
+  bool isSpecializable(DartType tp) {
+    return _interfaceRels.containsKey(tp);
+  }
+
+  Set<DartType> interfaces(DartType tp) {
+    if (_interfaceRels.containsKey(tp)) {
+      return _interfaceRels[tp];
+    }
+    return null;
+  }
+
+  DartType indexType(DartType tp) {
+    if (_indexedBy.containsKey(tp)) {
+      return _indexedBy[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> indexableElementTypes(DartType tp) {
+    if (_indexableElementOf.containsKey(tp)) {
+      return _indexableElementOf[tp];
+    }
+    return null;
+  }
+
+  bool isIndexableElementType(DartType tp) {
+    return _indexableElementOf.containsKey(tp);
+  }
+
+  DartType elementType(DartType tp) {
+    if (_subscriptsTo.containsKey(tp)) {
+      return _subscriptsTo[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> get iterableTypes1 {
+    return _iterableTypes1;
+  }
+
+  Set<String> uniOps(DartType tp) {
+    if (_uniOps.containsKey(tp)) {
+      return _uniOps[tp];
+    }
+    return <String>{};
+  }
+
+  Set<String> binOps(DartType tp) {
+    if (_binOps.containsKey(tp)) {
+      return _binOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<List<DartType>> binOpParameters(DartType tp, String op) {
+    if (_binOps.containsKey(tp) && _binOps[tp].containsKey(op)) {
+      return _binOps[tp][op];
+    }
+    return null;
+  }
+
+  Set<String> assignOps(DartType tp) {
+    if (_assignOps.containsKey(tp)) {
+      return _assignOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<DartType> assignOpRhs(DartType tp, String op) {
+    if (_assignOps.containsKey(tp) && _assignOps[tp].containsKey(op)) {
+      return _assignOps[tp][op];
+    }
+    return <DartType>{};
+  }
+
+  bool hasConstructor(DartType tp) {
+    return _constructors.containsKey(tp);
+  }
+
+  Set<String> constructors(DartType tp) {
+    if (_constructors.containsKey(tp)) {
+      return _constructors[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  List<DartType> constructorParameters(DartType tp, String constructor) {
+    if (_constructors.containsKey(tp) &&
+        _constructors[tp].containsKey(constructor)) {
+      return _constructors[tp][constructor];
+    }
+    return null;
+  }
+
+  Set<DartType> get allTypes {
+    return _allTypes;
+  }
+
+  // All types extracted from analyzer.
+  static const _allTypes = {
+    DartType.INT8LIST,
+    DartType.UINT8LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.INT16LIST,
+    DartType.UINT16LIST,
+    DartType.INT32LIST,
+    DartType.UINT32LIST,
+    DartType.INT64LIST,
+    DartType.UINT64LIST,
+    DartType.FLOAT32LIST,
+    DartType.FLOAT64LIST,
+    DartType.FLOAT32X4LIST,
+    DartType.INT32X4LIST,
+    DartType.FLOAT64X2LIST,
+    DartType.FLOAT32X4,
+    DartType.INT32X4,
+    DartType.FLOAT64X2,
+    DartType.BOOL,
+    DartType.DOUBLE,
+    DartType.DURATION,
+    DartType.INT,
+    DartType.NUM,
+    DartType.STRING,
+    DartType.LIST_BOOL,
+    DartType.LIST_DOUBLE,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_DOUBLE,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_DOUBLE,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_DOUBLE_BOOL,
+    DartType.MAP_DOUBLE_DOUBLE,
+    DartType.MAP_DOUBLE_INT,
+    DartType.MAP_DOUBLE_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_DOUBLE,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_DOUBLE,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+  };
+
+  // All List<E> types: LIST_INT, LIST_STRING, etc.
+  static const Set<DartType> _listTypes = {
+    DartType.FLOAT32LIST,
+    DartType.FLOAT32X4LIST,
+    DartType.FLOAT64LIST,
+    DartType.FLOAT64X2LIST,
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_DOUBLE,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All Set types: SET_INT, SET_STRING, etc.
+  static const Set<DartType> _setTypes = {
+    DartType.SET_BOOL,
+    DartType.SET_DOUBLE,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+  };
+
+  // All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
+  static const Set<DartType> _mapTypes = {
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_DOUBLE,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_DOUBLE_BOOL,
+    DartType.MAP_DOUBLE_DOUBLE,
+    DartType.MAP_DOUBLE_INT,
+    DartType.MAP_DOUBLE_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_DOUBLE,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_DOUBLE,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+  };
+
+  // All collection types: list, map and set types.
+  static const Set<DartType> _collectionTypes = {
+    DartType.FLOAT32LIST,
+    DartType.FLOAT32X4LIST,
+    DartType.FLOAT64LIST,
+    DartType.FLOAT64X2LIST,
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_DOUBLE,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_DOUBLE,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_DOUBLE_BOOL,
+    DartType.MAP_DOUBLE_DOUBLE,
+    DartType.MAP_DOUBLE_INT,
+    DartType.MAP_DOUBLE_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_DOUBLE,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_DOUBLE,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_DOUBLE,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All growable types: list, map, set and string types.
+  static const Set<DartType> _growableTypes = {
+    DartType.FLOAT32LIST,
+    DartType.FLOAT32X4LIST,
+    DartType.FLOAT64LIST,
+    DartType.FLOAT64X2LIST,
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_DOUBLE,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_DOUBLE,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_DOUBLE_BOOL,
+    DartType.MAP_DOUBLE_DOUBLE,
+    DartType.MAP_DOUBLE_INT,
+    DartType.MAP_DOUBLE_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_DOUBLE,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_DOUBLE,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_DOUBLE,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All trivially indexable types: Map types and List types.
+  // Elements of these can be written and read by [], unlike Set
+  // which uses getElementAt to access individual elements.
+  static const Set<DartType> _indexableTypes = {
+    DartType.FLOAT32LIST,
+    DartType.FLOAT32X4LIST,
+    DartType.FLOAT64LIST,
+    DartType.FLOAT64X2LIST,
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_DOUBLE,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_DOUBLE,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_DOUBLE_BOOL,
+    DartType.MAP_DOUBLE_DOUBLE,
+    DartType.MAP_DOUBLE_INT,
+    DartType.MAP_DOUBLE_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_DOUBLE,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_DOUBLE,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // Map type to the resulting type when subscripted.
+  // Example: List<String> subscripts to String.
+  static const Map<DartType, DartType> _subscriptsTo = {
+    DartType.DURATION: DartType.DURATION,
+    DartType.FLOAT32LIST: DartType.DOUBLE,
+    DartType.FLOAT32X4LIST: DartType.FLOAT32X4,
+    DartType.FLOAT64LIST: DartType.DOUBLE,
+    DartType.FLOAT64X2LIST: DartType.FLOAT64X2,
+    DartType.INT16LIST: DartType.INT,
+    DartType.INT32LIST: DartType.INT,
+    DartType.INT32X4LIST: DartType.INT32X4,
+    DartType.INT64LIST: DartType.INT,
+    DartType.INT8LIST: DartType.INT,
+    DartType.LIST_BOOL: DartType.BOOL,
+    DartType.LIST_DOUBLE: DartType.DOUBLE,
+    DartType.LIST_INT: DartType.INT,
+    DartType.LIST_STRING: DartType.STRING,
+    DartType.MAP_BOOL_BOOL: DartType.BOOL,
+    DartType.MAP_BOOL_DOUBLE: DartType.DOUBLE,
+    DartType.MAP_BOOL_INT: DartType.INT,
+    DartType.MAP_BOOL_STRING: DartType.STRING,
+    DartType.MAP_DOUBLE_BOOL: DartType.BOOL,
+    DartType.MAP_DOUBLE_DOUBLE: DartType.DOUBLE,
+    DartType.MAP_DOUBLE_INT: DartType.INT,
+    DartType.MAP_DOUBLE_STRING: DartType.STRING,
+    DartType.MAP_INT_BOOL: DartType.BOOL,
+    DartType.MAP_INT_DOUBLE: DartType.DOUBLE,
+    DartType.MAP_INT_INT: DartType.INT,
+    DartType.MAP_INT_STRING: DartType.STRING,
+    DartType.MAP_STRING_BOOL: DartType.BOOL,
+    DartType.MAP_STRING_DOUBLE: DartType.DOUBLE,
+    DartType.MAP_STRING_INT: DartType.INT,
+    DartType.MAP_STRING_STRING: DartType.STRING,
+    DartType.NUM: DartType.NUM,
+    DartType.SET_BOOL: DartType.BOOL,
+    DartType.SET_DOUBLE: DartType.DOUBLE,
+    DartType.SET_INT: DartType.INT,
+    DartType.SET_STRING: DartType.STRING,
+    DartType.STRING: DartType.STRING,
+    DartType.UINT16LIST: DartType.INT,
+    DartType.UINT32LIST: DartType.INT,
+    DartType.UINT64LIST: DartType.INT,
+    DartType.UINT8CLAMPEDLIST: DartType.INT,
+    DartType.UINT8LIST: DartType.INT,
+  };
+
+  // Map type to type required as index.
+  // Example: List<String> is indexed by int,
+  // Map<String, double> indexed by String.
+  static const Map<DartType, DartType> _indexedBy = {
+    DartType.FLOAT32LIST: DartType.INT,
+    DartType.FLOAT32X4LIST: DartType.INT,
+    DartType.FLOAT64LIST: DartType.INT,
+    DartType.FLOAT64X2LIST: DartType.INT,
+    DartType.INT16LIST: DartType.INT,
+    DartType.INT32LIST: DartType.INT,
+    DartType.INT32X4LIST: DartType.INT,
+    DartType.INT64LIST: DartType.INT,
+    DartType.INT8LIST: DartType.INT,
+    DartType.LIST_BOOL: DartType.INT,
+    DartType.LIST_DOUBLE: DartType.INT,
+    DartType.LIST_INT: DartType.INT,
+    DartType.LIST_STRING: DartType.INT,
+    DartType.MAP_BOOL_BOOL: DartType.BOOL,
+    DartType.MAP_BOOL_DOUBLE: DartType.BOOL,
+    DartType.MAP_BOOL_INT: DartType.BOOL,
+    DartType.MAP_BOOL_STRING: DartType.BOOL,
+    DartType.MAP_DOUBLE_BOOL: DartType.DOUBLE,
+    DartType.MAP_DOUBLE_DOUBLE: DartType.DOUBLE,
+    DartType.MAP_DOUBLE_INT: DartType.DOUBLE,
+    DartType.MAP_DOUBLE_STRING: DartType.DOUBLE,
+    DartType.MAP_INT_BOOL: DartType.INT,
+    DartType.MAP_INT_DOUBLE: DartType.INT,
+    DartType.MAP_INT_INT: DartType.INT,
+    DartType.MAP_INT_STRING: DartType.INT,
+    DartType.MAP_STRING_BOOL: DartType.STRING,
+    DartType.MAP_STRING_DOUBLE: DartType.STRING,
+    DartType.MAP_STRING_INT: DartType.STRING,
+    DartType.MAP_STRING_STRING: DartType.STRING,
+    DartType.UINT16LIST: DartType.INT,
+    DartType.UINT32LIST: DartType.INT,
+    DartType.UINT64LIST: DartType.INT,
+    DartType.UINT8CLAMPEDLIST: DartType.INT,
+    DartType.UINT8LIST: DartType.INT,
+  };
+
+  // Map type to a Set of types that contain it as an element.
+  // Example: String is element of List<String> and Map<int, String>
+  static const Map<DartType, Set<DartType>> _elementOf = {
+    DartType.BOOL: {
+      DartType.LIST_BOOL,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_DOUBLE_BOOL,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_STRING_BOOL,
+      DartType.SET_BOOL,
+    },
+    DartType.DOUBLE: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT64LIST,
+      DartType.LIST_DOUBLE,
+      DartType.MAP_BOOL_DOUBLE,
+      DartType.MAP_DOUBLE_DOUBLE,
+      DartType.MAP_INT_DOUBLE,
+      DartType.MAP_STRING_DOUBLE,
+      DartType.SET_DOUBLE,
+    },
+    DartType.DURATION: {
+      DartType.DURATION,
+    },
+    DartType.FLOAT32X4: {
+      DartType.FLOAT32X4LIST,
+    },
+    DartType.FLOAT64X2: {
+      DartType.FLOAT64X2LIST,
+    },
+    DartType.INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_DOUBLE_INT,
+      DartType.MAP_INT_INT,
+      DartType.MAP_STRING_INT,
+      DartType.SET_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.NUM: {
+      DartType.NUM,
+    },
+    DartType.STRING: {
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_DOUBLE_STRING,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_STRING_STRING,
+      DartType.SET_STRING,
+      DartType.STRING,
+    },
+  };
+
+  // Map type to a Set of types that contain it as an indexable element.
+  // Same as element of, but without Set types.
+  static const Map<DartType, Set<DartType>> _indexableElementOf = {
+    DartType.BOOL: {
+      DartType.LIST_BOOL,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_DOUBLE_BOOL,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_STRING_BOOL,
+    },
+    DartType.DOUBLE: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT64LIST,
+      DartType.LIST_DOUBLE,
+      DartType.MAP_BOOL_DOUBLE,
+      DartType.MAP_DOUBLE_DOUBLE,
+      DartType.MAP_INT_DOUBLE,
+      DartType.MAP_STRING_DOUBLE,
+    },
+    DartType.FLOAT32X4: {
+      DartType.FLOAT32X4LIST,
+    },
+    DartType.FLOAT64X2: {
+      DartType.FLOAT64X2LIST,
+    },
+    DartType.INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_DOUBLE_INT,
+      DartType.MAP_INT_INT,
+      DartType.MAP_STRING_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.STRING: {
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_DOUBLE_STRING,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_STRING_STRING,
+    },
+  };
+
+  // All iterable types: Set types + List types.
+  // These can be used in for(x in <iterable type>),
+  // therefore Map is not included.
+  static const Set<DartType> _iterableTypes1 = {
+    DartType.FLOAT32LIST,
+    DartType.FLOAT32X4LIST,
+    DartType.FLOAT64LIST,
+    DartType.FLOAT64X2LIST,
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_DOUBLE,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // Map Interface type to Set of types that implement it.
+  // Example: interface num is implemented by int and double.
+  static const Map<DartType, Set<DartType>> _interfaceRels = {
+    DartType.COMPARABLE_DURATION: {
+      DartType.DURATION,
+    },
+    DartType.COMPARABLE_NUM: {
+      DartType.DOUBLE,
+      DartType.INT,
+      DartType.NUM,
+    },
+    DartType.COMPARABLE_STRING: {
+      DartType.STRING,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_BOOL: {
+      DartType.LIST_BOOL,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_DOUBLE: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT64LIST,
+      DartType.LIST_DOUBLE,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_E: {
+      DartType.LIST_BOOL,
+      DartType.LIST_DOUBLE,
+      DartType.LIST_INT,
+      DartType.LIST_STRING,
+      DartType.SET_BOOL,
+      DartType.SET_DOUBLE,
+      DartType.SET_INT,
+      DartType.SET_STRING,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_FLOAT32X4: {
+      DartType.FLOAT32X4LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_FLOAT64X2: {
+      DartType.FLOAT64X2LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_STRING: {
+      DartType.LIST_STRING,
+    },
+    DartType.ITERABLE_DOUBLE: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT64LIST,
+    },
+    DartType.ITERABLE_E: {
+      DartType.LIST_BOOL,
+      DartType.LIST_DOUBLE,
+      DartType.LIST_INT,
+      DartType.LIST_STRING,
+      DartType.SET_BOOL,
+      DartType.SET_DOUBLE,
+      DartType.SET_INT,
+      DartType.SET_STRING,
+    },
+    DartType.ITERABLE_FLOAT32X4: {
+      DartType.FLOAT32X4LIST,
+    },
+    DartType.ITERABLE_FLOAT64X2: {
+      DartType.FLOAT64X2LIST,
+    },
+    DartType.ITERABLE_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.ITERABLE_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.LIST_DOUBLE: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT64LIST,
+      DartType.LIST_DOUBLE,
+    },
+    DartType.LIST_FLOAT32X4: {
+      DartType.FLOAT32X4LIST,
+    },
+    DartType.LIST_FLOAT64X2: {
+      DartType.FLOAT64X2LIST,
+    },
+    DartType.LIST_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.LIST_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.NUM: {
+      DartType.DOUBLE,
+      DartType.INT,
+      DartType.NUM,
+    },
+    DartType.OBJECT: {
+      DartType.BOOL,
+      DartType.DOUBLE,
+      DartType.DURATION,
+      DartType.FLOAT32LIST,
+      DartType.FLOAT32X4,
+      DartType.FLOAT32X4LIST,
+      DartType.FLOAT64LIST,
+      DartType.FLOAT64X2,
+      DartType.FLOAT64X2LIST,
+      DartType.INT,
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT32X4,
+      DartType.INT32X4LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_BOOL,
+      DartType.LIST_DOUBLE,
+      DartType.LIST_INT,
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_BOOL_DOUBLE,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_DOUBLE_BOOL,
+      DartType.MAP_DOUBLE_DOUBLE,
+      DartType.MAP_DOUBLE_INT,
+      DartType.MAP_DOUBLE_STRING,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_INT_DOUBLE,
+      DartType.MAP_INT_INT,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_STRING_BOOL,
+      DartType.MAP_STRING_DOUBLE,
+      DartType.MAP_STRING_INT,
+      DartType.MAP_STRING_STRING,
+      DartType.NUM,
+      DartType.SET_BOOL,
+      DartType.SET_DOUBLE,
+      DartType.SET_INT,
+      DartType.SET_STRING,
+      DartType.STRING,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.PATTERN: {
+      DartType.STRING,
+    },
+    DartType.TYPEDDATA: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT32X4LIST,
+      DartType.FLOAT64LIST,
+      DartType.FLOAT64X2LIST,
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT32X4LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType._TYPEDFLOATLIST: {
+      DartType.FLOAT32LIST,
+      DartType.FLOAT64LIST,
+    },
+    DartType._TYPEDINTLIST: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+  };
+
+  // Map type to a list of constructors names with a list of constructor
+  // parameter types.
+  static const Map<DartType, Map<String, List<DartType>>> _constructors = {
+    DartType.DURATION: {
+      '': [],
+    },
+    DartType.FLOAT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_DOUBLE,
+      ],
+    },
+    DartType.FLOAT32X4: {
+      '': [
+        DartType.DOUBLE,
+        DartType.DOUBLE,
+        DartType.DOUBLE,
+        DartType.DOUBLE,
+      ],
+      'splat': [
+        DartType.DOUBLE,
+      ],
+      'zero': [],
+    },
+    DartType.FLOAT32X4LIST: {
+      '': [
+        DartType.INT,
+      ],
+    },
+    DartType.FLOAT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_DOUBLE,
+      ],
+    },
+    DartType.FLOAT64X2: {
+      '': [
+        DartType.DOUBLE,
+        DartType.DOUBLE,
+      ],
+      'splat': [
+        DartType.DOUBLE,
+      ],
+      'zero': [],
+    },
+    DartType.FLOAT64X2LIST: {
+      '': [
+        DartType.INT,
+      ],
+    },
+    DartType.INT16LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT32X4: {
+      '': [
+        DartType.INT,
+        DartType.INT,
+        DartType.INT,
+        DartType.INT,
+      ],
+    },
+    DartType.INT32X4LIST: {
+      '': [
+        DartType.INT,
+      ],
+    },
+    DartType.INT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT8LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT16LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT8CLAMPEDLIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT8LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+  };
+
+  // Map type to a list of binary operators with set of the respective
+  // types for the first and second operand.
+  static const Map<DartType, Map<String, Set<List<DartType>>>> _binOps = {
+    DartType.BOOL: {
+      '&': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '&&': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '<': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '<=': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '==': {
+        [
+          DartType.NUM,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.STRING,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_BOOL,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_DOUBLE,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_INT,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_STRING,
+          DartType.OBJECT,
+        ],
+      },
+      '>': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '>=': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '^': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '|': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '||': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+    },
+    DartType.DOUBLE: {
+      '%': {
+        [
+          DartType.DOUBLE,
+          DartType.NUM,
+        ],
+      },
+      '*': {
+        [
+          DartType.DOUBLE,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.DOUBLE,
+          DartType.NUM,
+        ],
+      },
+      '-': {
+        [
+          DartType.DOUBLE,
+          DartType.NUM,
+        ],
+      },
+      '/': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.DOUBLE,
+          DartType.DOUBLE,
+        ],
+      },
+    },
+    DartType.DURATION: {
+      '*': {
+        [
+          DartType.DURATION,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '-': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '??': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '~/': {
+        [
+          DartType.DURATION,
+          DartType.INT,
+        ],
+      },
+    },
+    DartType.FLOAT32X4: {
+      '*': {
+        [
+          DartType.FLOAT32X4,
+          DartType.FLOAT32X4,
+        ],
+      },
+      '+': {
+        [
+          DartType.FLOAT32X4,
+          DartType.FLOAT32X4,
+        ],
+      },
+      '-': {
+        [
+          DartType.FLOAT32X4,
+          DartType.FLOAT32X4,
+        ],
+      },
+      '/': {
+        [
+          DartType.FLOAT32X4,
+          DartType.FLOAT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.FLOAT32X4,
+          DartType.FLOAT32X4,
+        ],
+      },
+    },
+    DartType.FLOAT64X2: {
+      '*': {
+        [
+          DartType.FLOAT64X2,
+          DartType.FLOAT64X2,
+        ],
+      },
+      '+': {
+        [
+          DartType.FLOAT64X2,
+          DartType.FLOAT64X2,
+        ],
+      },
+      '-': {
+        [
+          DartType.FLOAT64X2,
+          DartType.FLOAT64X2,
+        ],
+      },
+      '/': {
+        [
+          DartType.FLOAT64X2,
+          DartType.FLOAT64X2,
+        ],
+      },
+      '??': {
+        [
+          DartType.FLOAT64X2,
+          DartType.FLOAT64X2,
+        ],
+      },
+    },
+    DartType.INT: {
+      '&': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '<<': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '>>': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '^': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '|': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '~/': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+    },
+    DartType.INT32X4: {
+      '&': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '+': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '-': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '^': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '|': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+    },
+    DartType.LIST_BOOL: {
+      '+': {
+        [
+          DartType.LIST_BOOL,
+          DartType.LIST_BOOL,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_BOOL,
+          DartType.LIST_BOOL,
+        ],
+      },
+    },
+    DartType.LIST_DOUBLE: {
+      '+': {
+        [
+          DartType.LIST_DOUBLE,
+          DartType.LIST_DOUBLE,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_DOUBLE,
+          DartType.LIST_DOUBLE,
+        ],
+      },
+    },
+    DartType.LIST_FLOAT32X4: {
+      '+': {
+        [
+          DartType.FLOAT32X4LIST,
+          DartType.LIST_FLOAT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_FLOAT32X4,
+          DartType.LIST_FLOAT32X4,
+        ],
+      },
+    },
+    DartType.LIST_FLOAT64X2: {
+      '+': {
+        [
+          DartType.FLOAT64X2LIST,
+          DartType.LIST_FLOAT64X2,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_FLOAT64X2,
+          DartType.LIST_FLOAT64X2,
+        ],
+      },
+    },
+    DartType.LIST_INT: {
+      '+': {
+        [
+          DartType.LIST_INT,
+          DartType.LIST_INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_INT,
+          DartType.LIST_INT,
+        ],
+      },
+    },
+    DartType.LIST_INT32X4: {
+      '+': {
+        [
+          DartType.INT32X4LIST,
+          DartType.LIST_INT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_INT32X4,
+          DartType.LIST_INT32X4,
+        ],
+      },
+    },
+    DartType.LIST_STRING: {
+      '+': {
+        [
+          DartType.LIST_STRING,
+          DartType.LIST_STRING,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_STRING,
+          DartType.LIST_STRING,
+        ],
+      },
+    },
+    DartType.NUM: {
+      '%': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '*': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '-': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+    },
+    DartType.STRING: {
+      '*': {
+        [
+          DartType.STRING,
+          DartType.INT,
+        ],
+      },
+      '+': {
+        [
+          DartType.STRING,
+          DartType.STRING,
+        ],
+      },
+      '??': {
+        [
+          DartType.STRING,
+          DartType.STRING,
+        ],
+      },
+    },
+  };
+
+  // Map type to a list of available unary operators.
+  static const Map<DartType, Set<String>> _uniOps = {
+    DartType.BOOL: {'!'},
+    DartType.DOUBLE: {'-'},
+    DartType.DURATION: {'-'},
+    DartType.FLOAT32X4: {'-'},
+    DartType.FLOAT64X2: {'-'},
+    DartType.INT: {'-', '~'},
+    DartType.NUM: {'-'},
+  };
+
+  // Map type to a list of assignment operators with a set of the
+  // assignable right hand side types.
+  static const Map<DartType, Map<String, Set<DartType>>> _assignOps = {
+    DartType.BOOL: {
+      '=': {
+        DartType.BOOL,
+      },
+      '??=': {
+        DartType.BOOL,
+      },
+    },
+    DartType.DOUBLE: {
+      '=': {
+        DartType.DOUBLE,
+      },
+      '??=': {
+        DartType.DOUBLE,
+      },
+      '+=': {
+        DartType.NUM,
+      },
+      '-=': {
+        DartType.NUM,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '%=': {
+        DartType.NUM,
+      },
+      '/=': {
+        DartType.NUM,
+      },
+    },
+    DartType.DURATION: {
+      '=': {
+        DartType.DURATION,
+      },
+      '??=': {
+        DartType.DURATION,
+      },
+      '+=': {
+        DartType.DURATION,
+      },
+      '-=': {
+        DartType.DURATION,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '~/=': {
+        DartType.INT,
+      },
+    },
+    DartType.FLOAT32LIST: {
+      '=': {
+        DartType.FLOAT32LIST,
+      },
+      '??=': {
+        DartType.FLOAT32LIST,
+      },
+    },
+    DartType.FLOAT32X4: {
+      '=': {
+        DartType.FLOAT32X4,
+      },
+      '??=': {
+        DartType.FLOAT32X4,
+      },
+      '+=': {
+        DartType.FLOAT32X4,
+      },
+      '-=': {
+        DartType.FLOAT32X4,
+      },
+      '*=': {
+        DartType.FLOAT32X4,
+      },
+      '/=': {
+        DartType.FLOAT32X4,
+      },
+    },
+    DartType.FLOAT32X4LIST: {
+      '=': {
+        DartType.FLOAT32X4LIST,
+      },
+      '??=': {
+        DartType.FLOAT32X4LIST,
+      },
+    },
+    DartType.FLOAT64LIST: {
+      '=': {
+        DartType.FLOAT64LIST,
+      },
+      '??=': {
+        DartType.FLOAT64LIST,
+      },
+    },
+    DartType.FLOAT64X2: {
+      '=': {
+        DartType.FLOAT64X2,
+      },
+      '??=': {
+        DartType.FLOAT64X2,
+      },
+      '+=': {
+        DartType.FLOAT64X2,
+      },
+      '-=': {
+        DartType.FLOAT64X2,
+      },
+      '*=': {
+        DartType.FLOAT64X2,
+      },
+      '/=': {
+        DartType.FLOAT64X2,
+      },
+    },
+    DartType.FLOAT64X2LIST: {
+      '=': {
+        DartType.FLOAT64X2LIST,
+      },
+      '??=': {
+        DartType.FLOAT64X2LIST,
+      },
+    },
+    DartType.INT: {
+      '~/=': {
+        DartType.NUM,
+      },
+      '=': {
+        DartType.INT,
+      },
+      '??=': {
+        DartType.INT,
+      },
+      '&=': {
+        DartType.INT,
+      },
+      '|=': {
+        DartType.INT,
+      },
+      '^=': {
+        DartType.INT,
+      },
+      '<<=': {
+        DartType.INT,
+      },
+      '>>=': {
+        DartType.INT,
+      },
+    },
+    DartType.INT16LIST: {
+      '=': {
+        DartType.INT16LIST,
+      },
+      '??=': {
+        DartType.INT16LIST,
+      },
+    },
+    DartType.INT32LIST: {
+      '=': {
+        DartType.INT32LIST,
+      },
+      '??=': {
+        DartType.INT32LIST,
+      },
+    },
+    DartType.INT32X4: {
+      '=': {
+        DartType.INT32X4,
+      },
+      '??=': {
+        DartType.INT32X4,
+      },
+      '|=': {
+        DartType.INT32X4,
+      },
+      '&=': {
+        DartType.INT32X4,
+      },
+      '^=': {
+        DartType.INT32X4,
+      },
+      '+=': {
+        DartType.INT32X4,
+      },
+      '-=': {
+        DartType.INT32X4,
+      },
+    },
+    DartType.INT32X4LIST: {
+      '=': {
+        DartType.INT32X4LIST,
+      },
+      '??=': {
+        DartType.INT32X4LIST,
+      },
+    },
+    DartType.INT64LIST: {
+      '=': {
+        DartType.INT64LIST,
+      },
+      '??=': {
+        DartType.INT64LIST,
+      },
+    },
+    DartType.INT8LIST: {
+      '=': {
+        DartType.INT8LIST,
+      },
+      '??=': {
+        DartType.INT8LIST,
+      },
+    },
+    DartType.LIST_BOOL: {
+      '=': {
+        DartType.LIST_BOOL,
+      },
+      '??=': {
+        DartType.LIST_BOOL,
+      },
+      '+=': {
+        DartType.LIST_BOOL,
+      },
+    },
+    DartType.LIST_DOUBLE: {
+      '=': {
+        DartType.LIST_DOUBLE,
+      },
+      '??=': {
+        DartType.LIST_DOUBLE,
+      },
+      '+=': {
+        DartType.LIST_DOUBLE,
+      },
+    },
+    DartType.LIST_FLOAT32X4: {
+      '+=': {
+        DartType.LIST_FLOAT32X4,
+      },
+    },
+    DartType.LIST_FLOAT64X2: {
+      '+=': {
+        DartType.LIST_FLOAT64X2,
+      },
+    },
+    DartType.LIST_INT: {
+      '+=': {
+        DartType.LIST_INT,
+      },
+      '=': {
+        DartType.LIST_INT,
+      },
+      '??=': {
+        DartType.LIST_INT,
+      },
+    },
+    DartType.LIST_INT32X4: {
+      '+=': {
+        DartType.LIST_INT32X4,
+      },
+    },
+    DartType.LIST_STRING: {
+      '=': {
+        DartType.LIST_STRING,
+      },
+      '??=': {
+        DartType.LIST_STRING,
+      },
+      '+=': {
+        DartType.LIST_STRING,
+      },
+    },
+    DartType.MAP_BOOL_BOOL: {
+      '=': {
+        DartType.MAP_BOOL_BOOL,
+      },
+      '??=': {
+        DartType.MAP_BOOL_BOOL,
+      },
+    },
+    DartType.MAP_BOOL_DOUBLE: {
+      '=': {
+        DartType.MAP_BOOL_DOUBLE,
+      },
+      '??=': {
+        DartType.MAP_BOOL_DOUBLE,
+      },
+    },
+    DartType.MAP_BOOL_INT: {
+      '=': {
+        DartType.MAP_BOOL_INT,
+      },
+      '??=': {
+        DartType.MAP_BOOL_INT,
+      },
+    },
+    DartType.MAP_BOOL_STRING: {
+      '=': {
+        DartType.MAP_BOOL_STRING,
+      },
+      '??=': {
+        DartType.MAP_BOOL_STRING,
+      },
+    },
+    DartType.MAP_DOUBLE_BOOL: {
+      '=': {
+        DartType.MAP_DOUBLE_BOOL,
+      },
+      '??=': {
+        DartType.MAP_DOUBLE_BOOL,
+      },
+    },
+    DartType.MAP_DOUBLE_DOUBLE: {
+      '=': {
+        DartType.MAP_DOUBLE_DOUBLE,
+      },
+      '??=': {
+        DartType.MAP_DOUBLE_DOUBLE,
+      },
+    },
+    DartType.MAP_DOUBLE_INT: {
+      '=': {
+        DartType.MAP_DOUBLE_INT,
+      },
+      '??=': {
+        DartType.MAP_DOUBLE_INT,
+      },
+    },
+    DartType.MAP_DOUBLE_STRING: {
+      '=': {
+        DartType.MAP_DOUBLE_STRING,
+      },
+      '??=': {
+        DartType.MAP_DOUBLE_STRING,
+      },
+    },
+    DartType.MAP_INT_BOOL: {
+      '=': {
+        DartType.MAP_INT_BOOL,
+      },
+      '??=': {
+        DartType.MAP_INT_BOOL,
+      },
+    },
+    DartType.MAP_INT_DOUBLE: {
+      '=': {
+        DartType.MAP_INT_DOUBLE,
+      },
+      '??=': {
+        DartType.MAP_INT_DOUBLE,
+      },
+    },
+    DartType.MAP_INT_INT: {
+      '=': {
+        DartType.MAP_INT_INT,
+      },
+      '??=': {
+        DartType.MAP_INT_INT,
+      },
+    },
+    DartType.MAP_INT_STRING: {
+      '=': {
+        DartType.MAP_INT_STRING,
+      },
+      '??=': {
+        DartType.MAP_INT_STRING,
+      },
+    },
+    DartType.MAP_STRING_BOOL: {
+      '=': {
+        DartType.MAP_STRING_BOOL,
+      },
+      '??=': {
+        DartType.MAP_STRING_BOOL,
+      },
+    },
+    DartType.MAP_STRING_DOUBLE: {
+      '=': {
+        DartType.MAP_STRING_DOUBLE,
+      },
+      '??=': {
+        DartType.MAP_STRING_DOUBLE,
+      },
+    },
+    DartType.MAP_STRING_INT: {
+      '=': {
+        DartType.MAP_STRING_INT,
+      },
+      '??=': {
+        DartType.MAP_STRING_INT,
+      },
+    },
+    DartType.MAP_STRING_STRING: {
+      '=': {
+        DartType.MAP_STRING_STRING,
+      },
+      '??=': {
+        DartType.MAP_STRING_STRING,
+      },
+    },
+    DartType.NUM: {
+      '=': {
+        DartType.NUM,
+      },
+      '??=': {
+        DartType.NUM,
+      },
+      '+=': {
+        DartType.NUM,
+      },
+      '-=': {
+        DartType.NUM,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '%=': {
+        DartType.NUM,
+      },
+    },
+    DartType.SET_BOOL: {
+      '=': {
+        DartType.SET_BOOL,
+      },
+      '??=': {
+        DartType.SET_BOOL,
+      },
+    },
+    DartType.SET_DOUBLE: {
+      '=': {
+        DartType.SET_DOUBLE,
+      },
+      '??=': {
+        DartType.SET_DOUBLE,
+      },
+    },
+    DartType.SET_INT: {
+      '=': {
+        DartType.SET_INT,
+      },
+      '??=': {
+        DartType.SET_INT,
+      },
+    },
+    DartType.SET_STRING: {
+      '=': {
+        DartType.SET_STRING,
+      },
+      '??=': {
+        DartType.SET_STRING,
+      },
+    },
+    DartType.STRING: {
+      '=': {
+        DartType.STRING,
+      },
+      '??=': {
+        DartType.STRING,
+      },
+      '+=': {
+        DartType.STRING,
+      },
+      '*=': {
+        DartType.INT,
+      },
+    },
+    DartType.UINT16LIST: {
+      '=': {
+        DartType.UINT16LIST,
+      },
+      '??=': {
+        DartType.UINT16LIST,
+      },
+    },
+    DartType.UINT32LIST: {
+      '=': {
+        DartType.UINT32LIST,
+      },
+      '??=': {
+        DartType.UINT32LIST,
+      },
+    },
+    DartType.UINT64LIST: {
+      '=': {
+        DartType.UINT64LIST,
+      },
+      '??=': {
+        DartType.UINT64LIST,
+      },
+    },
+    DartType.UINT8CLAMPEDLIST: {
+      '=': {
+        DartType.UINT8CLAMPEDLIST,
+      },
+      '??=': {
+        DartType.UINT8CLAMPEDLIST,
+      },
+    },
+    DartType.UINT8LIST: {
+      '=': {
+        DartType.UINT8LIST,
+      },
+      '??=': {
+        DartType.UINT8LIST,
+      },
+    },
+  };
+}
+
+class DartTypeNoFpFlatTp extends DartType {
+  final String name;
+  const DartTypeNoFpFlatTp._withName(this.name) : super._withName(name);
+  const DartTypeNoFpFlatTp() : name = null;
+  static bool isListType(DartType tp) {
+    return DartType._listTypes.contains(tp);
+  }
+
+  static bool isMapType(DartType tp) {
+    return DartType._mapTypes.contains(tp);
+  }
+
+  static bool isCollectionType(DartType tp) {
+    return DartType._collectionTypes.contains(tp);
+  }
+
+  static bool isGrowableType(DartType tp) {
+    return DartType._growableTypes.contains(tp);
+  }
+
+  static bool isComplexType(DartType tp) {
+    return DartType._complexTypes.contains(tp);
+  }
+
+  bool isInterfaceOfType(DartType tp, DartType iTp) {
+    return _interfaceRels.containsKey(iTp) && _interfaceRels[iTp].contains(tp);
+  }
+
+  Set<DartType> get mapTypes {
+    return _mapTypes;
+  }
+
+  bool isSpecializable(DartType tp) {
+    return _interfaceRels.containsKey(tp);
+  }
+
+  Set<DartType> interfaces(DartType tp) {
+    if (_interfaceRels.containsKey(tp)) {
+      return _interfaceRels[tp];
+    }
+    return null;
+  }
+
+  DartType indexType(DartType tp) {
+    if (_indexedBy.containsKey(tp)) {
+      return _indexedBy[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> indexableElementTypes(DartType tp) {
+    if (_indexableElementOf.containsKey(tp)) {
+      return _indexableElementOf[tp];
+    }
+    return null;
+  }
+
+  bool isIndexableElementType(DartType tp) {
+    return _indexableElementOf.containsKey(tp);
+  }
+
+  DartType elementType(DartType tp) {
+    if (_subscriptsTo.containsKey(tp)) {
+      return _subscriptsTo[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> get iterableTypes1 {
+    return _iterableTypes1;
+  }
+
+  Set<String> uniOps(DartType tp) {
+    if (_uniOps.containsKey(tp)) {
+      return _uniOps[tp];
+    }
+    return <String>{};
+  }
+
+  Set<String> binOps(DartType tp) {
+    if (_binOps.containsKey(tp)) {
+      return _binOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<List<DartType>> binOpParameters(DartType tp, String op) {
+    if (_binOps.containsKey(tp) && _binOps[tp].containsKey(op)) {
+      return _binOps[tp][op];
+    }
+    return null;
+  }
+
+  Set<String> assignOps(DartType tp) {
+    if (_assignOps.containsKey(tp)) {
+      return _assignOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<DartType> assignOpRhs(DartType tp, String op) {
+    if (_assignOps.containsKey(tp) && _assignOps[tp].containsKey(op)) {
+      return _assignOps[tp][op];
+    }
+    return <DartType>{};
+  }
+
+  bool hasConstructor(DartType tp) {
+    return _constructors.containsKey(tp);
+  }
+
+  Set<String> constructors(DartType tp) {
+    if (_constructors.containsKey(tp)) {
+      return _constructors[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  List<DartType> constructorParameters(DartType tp, String constructor) {
+    if (_constructors.containsKey(tp) &&
+        _constructors[tp].containsKey(constructor)) {
+      return _constructors[tp][constructor];
+    }
+    return null;
+  }
+
+  Set<DartType> get allTypes {
+    return _allTypes;
+  }
+
+  // All types extracted from analyzer.
+  static const _allTypes = {
+    DartType.INT8LIST,
+    DartType.UINT8LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.INT16LIST,
+    DartType.UINT16LIST,
+    DartType.INT32LIST,
+    DartType.UINT32LIST,
+    DartType.INT64LIST,
+    DartType.UINT64LIST,
+    DartType.INT32X4LIST,
+    DartType.INT32X4,
+    DartType.BOOL,
+    DartType.DURATION,
+    DartType.INT,
+    DartType.NUM,
+    DartType.STRING,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+  };
+
+  // All List<E> types: LIST_INT, LIST_STRING, etc.
+  static const Set<DartType> _listTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All Set types: SET_INT, SET_STRING, etc.
+  static const Set<DartType> _setTypes = {
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+  };
+
+  // All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
+  static const Set<DartType> _mapTypes = {
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+  };
+
+  // All collection types: list, map and set types.
+  static const Set<DartType> _collectionTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All growable types: list, map, set and string types.
+  static const Set<DartType> _growableTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.SET_BOOL,
+    DartType.SET_INT,
+    DartType.SET_STRING,
+    DartType.STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // All trivially indexable types: Map types and List types.
+  // Elements of these can be written and read by [], unlike Set
+  // which uses getElementAt to access individual elements.
+  static const Set<DartType> _indexableTypes = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.MAP_BOOL_BOOL,
+    DartType.MAP_BOOL_INT,
+    DartType.MAP_BOOL_STRING,
+    DartType.MAP_INT_BOOL,
+    DartType.MAP_INT_INT,
+    DartType.MAP_INT_STRING,
+    DartType.MAP_STRING_BOOL,
+    DartType.MAP_STRING_INT,
+    DartType.MAP_STRING_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // Map type to the resulting type when subscripted.
+  // Example: List<String> subscripts to String.
+  static const Map<DartType, DartType> _subscriptsTo = {
+    DartType.DURATION: DartType.DURATION,
+    DartType.INT16LIST: DartType.INT,
+    DartType.INT32LIST: DartType.INT,
+    DartType.INT32X4LIST: DartType.INT32X4,
+    DartType.INT64LIST: DartType.INT,
+    DartType.INT8LIST: DartType.INT,
+    DartType.LIST_BOOL: DartType.BOOL,
+    DartType.LIST_INT: DartType.INT,
+    DartType.LIST_STRING: DartType.STRING,
+    DartType.MAP_BOOL_BOOL: DartType.BOOL,
+    DartType.MAP_BOOL_INT: DartType.INT,
+    DartType.MAP_BOOL_STRING: DartType.STRING,
+    DartType.MAP_INT_BOOL: DartType.BOOL,
+    DartType.MAP_INT_INT: DartType.INT,
+    DartType.MAP_INT_STRING: DartType.STRING,
+    DartType.MAP_STRING_BOOL: DartType.BOOL,
+    DartType.MAP_STRING_INT: DartType.INT,
+    DartType.MAP_STRING_STRING: DartType.STRING,
+    DartType.NUM: DartType.NUM,
+    DartType.SET_BOOL: DartType.BOOL,
+    DartType.SET_INT: DartType.INT,
+    DartType.SET_STRING: DartType.STRING,
+    DartType.STRING: DartType.STRING,
+    DartType.UINT16LIST: DartType.INT,
+    DartType.UINT32LIST: DartType.INT,
+    DartType.UINT64LIST: DartType.INT,
+    DartType.UINT8CLAMPEDLIST: DartType.INT,
+    DartType.UINT8LIST: DartType.INT,
+  };
+
+  // Map type to type required as index.
+  // Example: List<String> is indexed by int,
+  // Map<String, double> indexed by String.
+  static const Map<DartType, DartType> _indexedBy = {
+    DartType.INT16LIST: DartType.INT,
+    DartType.INT32LIST: DartType.INT,
+    DartType.INT32X4LIST: DartType.INT,
+    DartType.INT64LIST: DartType.INT,
+    DartType.INT8LIST: DartType.INT,
+    DartType.LIST_BOOL: DartType.INT,
+    DartType.LIST_INT: DartType.INT,
+    DartType.LIST_STRING: DartType.INT,
+    DartType.MAP_BOOL_BOOL: DartType.BOOL,
+    DartType.MAP_BOOL_INT: DartType.BOOL,
+    DartType.MAP_BOOL_STRING: DartType.BOOL,
+    DartType.MAP_INT_BOOL: DartType.INT,
+    DartType.MAP_INT_INT: DartType.INT,
+    DartType.MAP_INT_STRING: DartType.INT,
+    DartType.MAP_STRING_BOOL: DartType.STRING,
+    DartType.MAP_STRING_INT: DartType.STRING,
+    DartType.MAP_STRING_STRING: DartType.STRING,
+    DartType.UINT16LIST: DartType.INT,
+    DartType.UINT32LIST: DartType.INT,
+    DartType.UINT64LIST: DartType.INT,
+    DartType.UINT8CLAMPEDLIST: DartType.INT,
+    DartType.UINT8LIST: DartType.INT,
+  };
+
+  // Map type to a Set of types that contain it as an element.
+  // Example: String is element of List<String> and Map<int, String>
+  static const Map<DartType, Set<DartType>> _elementOf = {
+    DartType.BOOL: {
+      DartType.LIST_BOOL,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_STRING_BOOL,
+      DartType.SET_BOOL,
+    },
+    DartType.DURATION: {
+      DartType.DURATION,
+    },
+    DartType.INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_INT_INT,
+      DartType.MAP_STRING_INT,
+      DartType.SET_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.NUM: {
+      DartType.NUM,
+    },
+    DartType.STRING: {
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_STRING_STRING,
+      DartType.SET_STRING,
+      DartType.STRING,
+    },
+  };
+
+  // Map type to a Set of types that contain it as an indexable element.
+  // Same as element of, but without Set types.
+  static const Map<DartType, Set<DartType>> _indexableElementOf = {
+    DartType.BOOL: {
+      DartType.LIST_BOOL,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_STRING_BOOL,
+    },
+    DartType.INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_INT_INT,
+      DartType.MAP_STRING_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.STRING: {
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_STRING_STRING,
+    },
+  };
+
+  // All iterable types: Set types + List types.
+  // These can be used in for(x in <iterable type>),
+  // therefore Map is not included.
+  static const Set<DartType> _iterableTypes1 = {
+    DartType.INT16LIST,
+    DartType.INT32LIST,
+    DartType.INT32X4LIST,
+    DartType.INT64LIST,
+    DartType.INT8LIST,
+    DartType.LIST_BOOL,
+    DartType.LIST_INT,
+    DartType.LIST_STRING,
+    DartType.UINT16LIST,
+    DartType.UINT32LIST,
+    DartType.UINT64LIST,
+    DartType.UINT8CLAMPEDLIST,
+    DartType.UINT8LIST,
+  };
+
+  // Map Interface type to Set of types that implement it.
+  // Example: interface num is implemented by int and double.
+  static const Map<DartType, Set<DartType>> _interfaceRels = {
+    DartType.COMPARABLE_DURATION: {
+      DartType.DURATION,
+    },
+    DartType.COMPARABLE_NUM: {
+      DartType.INT,
+      DartType.NUM,
+    },
+    DartType.COMPARABLE_STRING: {
+      DartType.STRING,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_BOOL: {
+      DartType.LIST_BOOL,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_E: {
+      DartType.LIST_BOOL,
+      DartType.LIST_INT,
+      DartType.LIST_STRING,
+      DartType.SET_BOOL,
+      DartType.SET_INT,
+      DartType.SET_STRING,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.EFFICIENTLENGTHITERABLE_STRING: {
+      DartType.LIST_STRING,
+    },
+    DartType.ITERABLE_E: {
+      DartType.LIST_BOOL,
+      DartType.LIST_INT,
+      DartType.LIST_STRING,
+      DartType.SET_BOOL,
+      DartType.SET_INT,
+      DartType.SET_STRING,
+    },
+    DartType.ITERABLE_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.ITERABLE_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.LIST_INT: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_INT,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.LIST_INT32X4: {
+      DartType.INT32X4LIST,
+    },
+    DartType.NUM: {
+      DartType.INT,
+      DartType.NUM,
+    },
+    DartType.OBJECT: {
+      DartType.BOOL,
+      DartType.DURATION,
+      DartType.INT,
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT32X4,
+      DartType.INT32X4LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.LIST_BOOL,
+      DartType.LIST_INT,
+      DartType.LIST_STRING,
+      DartType.MAP_BOOL_BOOL,
+      DartType.MAP_BOOL_INT,
+      DartType.MAP_BOOL_STRING,
+      DartType.MAP_INT_BOOL,
+      DartType.MAP_INT_INT,
+      DartType.MAP_INT_STRING,
+      DartType.MAP_STRING_BOOL,
+      DartType.MAP_STRING_INT,
+      DartType.MAP_STRING_STRING,
+      DartType.NUM,
+      DartType.SET_BOOL,
+      DartType.SET_INT,
+      DartType.SET_STRING,
+      DartType.STRING,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType.PATTERN: {
+      DartType.STRING,
+    },
+    DartType.TYPEDDATA: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT32X4LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+    DartType._TYPEDINTLIST: {
+      DartType.INT16LIST,
+      DartType.INT32LIST,
+      DartType.INT64LIST,
+      DartType.INT8LIST,
+      DartType.UINT16LIST,
+      DartType.UINT32LIST,
+      DartType.UINT64LIST,
+      DartType.UINT8CLAMPEDLIST,
+      DartType.UINT8LIST,
+    },
+  };
+
+  // Map type to a list of constructors names with a list of constructor
+  // parameter types.
+  static const Map<DartType, Map<String, List<DartType>>> _constructors = {
+    DartType.DURATION: {
+      '': [],
+    },
+    DartType.INT16LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT32X4: {
+      '': [
+        DartType.INT,
+        DartType.INT,
+        DartType.INT,
+        DartType.INT,
+      ],
+    },
+    DartType.INT32X4LIST: {
+      '': [
+        DartType.INT,
+      ],
+    },
+    DartType.INT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.INT8LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT16LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT32LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT64LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT8CLAMPEDLIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+    DartType.UINT8LIST: {
+      '': [
+        DartType.INT,
+      ],
+      'fromList': [
+        DartType.LIST_INT,
+      ],
+    },
+  };
+
+  // Map type to a list of binary operators with set of the respective
+  // types for the first and second operand.
+  static const Map<DartType, Map<String, Set<List<DartType>>>> _binOps = {
+    DartType.BOOL: {
+      '&': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '&&': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '<': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '<=': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '==': {
+        [
+          DartType.NUM,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.STRING,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_BOOL,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_INT,
+          DartType.OBJECT,
+        ],
+        [
+          DartType.LIST_STRING,
+          DartType.OBJECT,
+        ],
+      },
+      '>': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '>=': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '^': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '|': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+      '||': {
+        [
+          DartType.BOOL,
+          DartType.BOOL,
+        ],
+      },
+    },
+    DartType.DURATION: {
+      '*': {
+        [
+          DartType.DURATION,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '-': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '??': {
+        [
+          DartType.DURATION,
+          DartType.DURATION,
+        ],
+      },
+      '~/': {
+        [
+          DartType.DURATION,
+          DartType.INT,
+        ],
+      },
+    },
+    DartType.INT: {
+      '&': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '<<': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '>>': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '^': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '|': {
+        [
+          DartType.INT,
+          DartType.INT,
+        ],
+      },
+      '~/': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+    },
+    DartType.INT32X4: {
+      '&': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '+': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '-': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '^': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+      '|': {
+        [
+          DartType.INT32X4,
+          DartType.INT32X4,
+        ],
+      },
+    },
+    DartType.LIST_BOOL: {
+      '+': {
+        [
+          DartType.LIST_BOOL,
+          DartType.LIST_BOOL,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_BOOL,
+          DartType.LIST_BOOL,
+        ],
+      },
+    },
+    DartType.LIST_FLOAT32X4: {
+      '??': {
+        [
+          DartType.LIST_FLOAT32X4,
+          DartType.LIST_FLOAT32X4,
+        ],
+      },
+    },
+    DartType.LIST_FLOAT64X2: {
+      '??': {
+        [
+          DartType.LIST_FLOAT64X2,
+          DartType.LIST_FLOAT64X2,
+        ],
+      },
+    },
+    DartType.LIST_INT: {
+      '+': {
+        [
+          DartType.LIST_INT,
+          DartType.LIST_INT,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_INT,
+          DartType.LIST_INT,
+        ],
+      },
+    },
+    DartType.LIST_INT32X4: {
+      '+': {
+        [
+          DartType.INT32X4LIST,
+          DartType.LIST_INT32X4,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_INT32X4,
+          DartType.LIST_INT32X4,
+        ],
+      },
+    },
+    DartType.LIST_STRING: {
+      '+': {
+        [
+          DartType.LIST_STRING,
+          DartType.LIST_STRING,
+        ],
+      },
+      '??': {
+        [
+          DartType.LIST_STRING,
+          DartType.LIST_STRING,
+        ],
+      },
+    },
+    DartType.NUM: {
+      '%': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '*': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '+': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '-': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+      '??': {
+        [
+          DartType.NUM,
+          DartType.NUM,
+        ],
+      },
+    },
+    DartType.STRING: {
+      '*': {
+        [
+          DartType.STRING,
+          DartType.INT,
+        ],
+      },
+      '+': {
+        [
+          DartType.STRING,
+          DartType.STRING,
+        ],
+      },
+      '??': {
+        [
+          DartType.STRING,
+          DartType.STRING,
+        ],
+      },
+    },
+  };
+
+  // Map type to a list of available unary operators.
+  static const Map<DartType, Set<String>> _uniOps = {
+    DartType.BOOL: {'!'},
+    DartType.DURATION: {'-'},
+    DartType.INT: {'-', '~'},
+    DartType.NUM: {'-'},
+  };
+
+  // Map type to a list of assignment operators with a set of the
+  // assignable right hand side types.
+  static const Map<DartType, Map<String, Set<DartType>>> _assignOps = {
+    DartType.BOOL: {
+      '=': {
+        DartType.BOOL,
+      },
+      '??=': {
+        DartType.BOOL,
+      },
+    },
+    DartType.DURATION: {
+      '=': {
+        DartType.DURATION,
+      },
+      '??=': {
+        DartType.DURATION,
+      },
+      '+=': {
+        DartType.DURATION,
+      },
+      '-=': {
+        DartType.DURATION,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '~/=': {
+        DartType.INT,
+      },
+    },
+    DartType.INT: {
+      '~/=': {
+        DartType.NUM,
+      },
+      '=': {
+        DartType.INT,
+      },
+      '??=': {
+        DartType.INT,
+      },
+      '&=': {
+        DartType.INT,
+      },
+      '|=': {
+        DartType.INT,
+      },
+      '^=': {
+        DartType.INT,
+      },
+      '<<=': {
+        DartType.INT,
+      },
+      '>>=': {
+        DartType.INT,
+      },
+    },
+    DartType.INT16LIST: {
+      '=': {
+        DartType.INT16LIST,
+      },
+      '??=': {
+        DartType.INT16LIST,
+      },
+    },
+    DartType.INT32LIST: {
+      '=': {
+        DartType.INT32LIST,
+      },
+      '??=': {
+        DartType.INT32LIST,
+      },
+    },
+    DartType.INT32X4: {
+      '=': {
+        DartType.INT32X4,
+      },
+      '??=': {
+        DartType.INT32X4,
+      },
+      '|=': {
+        DartType.INT32X4,
+      },
+      '&=': {
+        DartType.INT32X4,
+      },
+      '^=': {
+        DartType.INT32X4,
+      },
+      '+=': {
+        DartType.INT32X4,
+      },
+      '-=': {
+        DartType.INT32X4,
+      },
+    },
+    DartType.INT32X4LIST: {
+      '=': {
+        DartType.INT32X4LIST,
+      },
+      '??=': {
+        DartType.INT32X4LIST,
+      },
+    },
+    DartType.INT64LIST: {
+      '=': {
+        DartType.INT64LIST,
+      },
+      '??=': {
+        DartType.INT64LIST,
+      },
+    },
+    DartType.INT8LIST: {
+      '=': {
+        DartType.INT8LIST,
+      },
+      '??=': {
+        DartType.INT8LIST,
+      },
+    },
+    DartType.LIST_BOOL: {
+      '=': {
+        DartType.LIST_BOOL,
+      },
+      '??=': {
+        DartType.LIST_BOOL,
+      },
+      '+=': {
+        DartType.LIST_BOOL,
+      },
+    },
+    DartType.LIST_FLOAT32X4: {
+      '+=': {
+        DartType.LIST_FLOAT32X4,
+      },
+    },
+    DartType.LIST_FLOAT64X2: {
+      '+=': {
+        DartType.LIST_FLOAT64X2,
+      },
+    },
+    DartType.LIST_INT: {
+      '+=': {
+        DartType.LIST_INT,
+      },
+      '=': {
+        DartType.LIST_INT,
+      },
+      '??=': {
+        DartType.LIST_INT,
+      },
+    },
+    DartType.LIST_INT32X4: {
+      '+=': {
+        DartType.LIST_INT32X4,
+      },
+    },
+    DartType.LIST_STRING: {
+      '=': {
+        DartType.LIST_STRING,
+      },
+      '??=': {
+        DartType.LIST_STRING,
+      },
+      '+=': {
+        DartType.LIST_STRING,
+      },
+    },
+    DartType.MAP_BOOL_BOOL: {
+      '=': {
+        DartType.MAP_BOOL_BOOL,
+      },
+      '??=': {
+        DartType.MAP_BOOL_BOOL,
+      },
+    },
+    DartType.MAP_BOOL_INT: {
+      '=': {
+        DartType.MAP_BOOL_INT,
+      },
+      '??=': {
+        DartType.MAP_BOOL_INT,
+      },
+    },
+    DartType.MAP_BOOL_STRING: {
+      '=': {
+        DartType.MAP_BOOL_STRING,
+      },
+      '??=': {
+        DartType.MAP_BOOL_STRING,
+      },
+    },
+    DartType.MAP_INT_BOOL: {
+      '=': {
+        DartType.MAP_INT_BOOL,
+      },
+      '??=': {
+        DartType.MAP_INT_BOOL,
+      },
+    },
+    DartType.MAP_INT_INT: {
+      '=': {
+        DartType.MAP_INT_INT,
+      },
+      '??=': {
+        DartType.MAP_INT_INT,
+      },
+    },
+    DartType.MAP_INT_STRING: {
+      '=': {
+        DartType.MAP_INT_STRING,
+      },
+      '??=': {
+        DartType.MAP_INT_STRING,
+      },
+    },
+    DartType.MAP_STRING_BOOL: {
+      '=': {
+        DartType.MAP_STRING_BOOL,
+      },
+      '??=': {
+        DartType.MAP_STRING_BOOL,
+      },
+    },
+    DartType.MAP_STRING_INT: {
+      '=': {
+        DartType.MAP_STRING_INT,
+      },
+      '??=': {
+        DartType.MAP_STRING_INT,
+      },
+    },
+    DartType.MAP_STRING_STRING: {
+      '=': {
+        DartType.MAP_STRING_STRING,
+      },
+      '??=': {
+        DartType.MAP_STRING_STRING,
+      },
+    },
+    DartType.NUM: {
+      '=': {
+        DartType.NUM,
+      },
+      '??=': {
+        DartType.NUM,
+      },
+      '+=': {
+        DartType.NUM,
+      },
+      '-=': {
+        DartType.NUM,
+      },
+      '*=': {
+        DartType.NUM,
+      },
+      '%=': {
+        DartType.NUM,
+      },
+    },
+    DartType.SET_BOOL: {
+      '=': {
+        DartType.SET_BOOL,
+      },
+      '??=': {
+        DartType.SET_BOOL,
+      },
+    },
+    DartType.SET_INT: {
+      '=': {
+        DartType.SET_INT,
+      },
+      '??=': {
+        DartType.SET_INT,
+      },
+    },
+    DartType.SET_STRING: {
+      '=': {
+        DartType.SET_STRING,
+      },
+      '??=': {
+        DartType.SET_STRING,
+      },
+    },
+    DartType.STRING: {
+      '=': {
+        DartType.STRING,
+      },
+      '??=': {
+        DartType.STRING,
+      },
+      '+=': {
+        DartType.STRING,
+      },
+      '*=': {
+        DartType.INT,
+      },
+    },
+    DartType.UINT16LIST: {
+      '=': {
+        DartType.UINT16LIST,
+      },
+      '??=': {
+        DartType.UINT16LIST,
+      },
+    },
+    DartType.UINT32LIST: {
+      '=': {
+        DartType.UINT32LIST,
+      },
+      '??=': {
+        DartType.UINT32LIST,
+      },
+    },
+    DartType.UINT64LIST: {
+      '=': {
+        DartType.UINT64LIST,
+      },
+      '??=': {
+        DartType.UINT64LIST,
+      },
+    },
+    DartType.UINT8CLAMPEDLIST: {
+      '=': {
+        DartType.UINT8CLAMPEDLIST,
+      },
+      '??=': {
+        DartType.UINT8CLAMPEDLIST,
+      },
+    },
+    DartType.UINT8LIST: {
+      '=': {
+        DartType.UINT8LIST,
+      },
+      '??=': {
+        DartType.UINT8LIST,
+      },
+    },
+  };
+}
diff --git a/runtime/tools/dartfuzz/dartfuzz_values.dart b/runtime/tools/dartfuzz/dartfuzz_values.dart
deleted file mode 100644
index 7886ae6..0000000
--- a/runtime/tools/dartfuzz/dartfuzz_values.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Class that represents some common Dart types.
-///
-/// TODO(ajcbik): generalize Dart types
-///
-class DartType {
-  final String name;
-
-  const DartType._withName(this.name);
-
-  static const VOID = DartType._withName('void');
-  static const BOOL = DartType._withName('bool');
-  static const INT = DartType._withName('int');
-  static const DOUBLE = DartType._withName('double');
-  static const STRING = DartType._withName('String');
-  static const INT_LIST = DartType._withName('List<int>');
-  static const INT_SET = DartType._withName('Set<int>');
-  static const INT_STRING_MAP = DartType._withName('Map<int, String>');
-
-  // All value types.
-  static const allTypes = [
-    BOOL,
-    INT,
-    DOUBLE,
-    STRING,
-    INT_LIST,
-    INT_SET,
-    INT_STRING_MAP
-  ];
-}
-
-/// Class with interesting values for fuzzing.
-class DartFuzzValues {
-  // Interesting characters.
-  static const List<String> interestingChars = [
-    '\\u2665',
-    '\\u{1f600}', // rune
-  ];
-
-  // Regular characters.
-  static const regularChars =
-      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+- ';
-
-  // Interesting integer values.
-  static const List<int> interestingIntegers = [
-    0x0000000000000000,
-    0x0000000000000001,
-    0x0000000000000010,
-    0x0000000000000020,
-    0x0000000000000040,
-    0x0000000000000064,
-    0x000000000000007f,
-    0x0000000000000080,
-    0x0000000000000081,
-    0x00000000000000ff,
-    0x0000000000000100,
-    0x0000000000000200,
-    0x00000000000003e8,
-    0x0000000000000400,
-    0x0000000000001000,
-    0x0000000000007fff,
-    0x0000000000008000,
-    0x0000000000008001,
-    0x000000000000ffff,
-    0x0000000000010000,
-    0x0000000005ffff05,
-    0x000000007fffffff,
-    0x0000000080000000,
-    0x0000000080000001,
-    0x00000000ffffffff,
-    0x0000000100000000,
-    0x0000000100000001,
-    0x0000000100000010,
-    0x0000000100000020,
-    0x0000000100000040,
-    0x0000000100000064,
-    0x000000010000007f,
-    0x0000000100000080,
-    0x0000000100000081,
-    0x00000001000000ff,
-    0x0000000100000100,
-    0x0000000100000200,
-    0x00000001000003e8,
-    0x0000000100000400,
-    0x0000000100001000,
-    0x0000000100007fff,
-    0x0000000100008000,
-    0x0000000100008001,
-    0x000000010000ffff,
-    0x0000000100010000,
-    0x0000000105ffff05,
-    0x000000017fffffff,
-    0x0000000180000000,
-    0x0000000180000001,
-    0x00000001ffffffff,
-    0x7fffffff00000000,
-    0x7fffffff00000001,
-    0x7fffffff00000010,
-    0x7fffffff00000020,
-    0x7fffffff00000040,
-    0x7fffffff00000064,
-    0x7fffffff0000007f,
-    0x7fffffff00000080,
-    0x7fffffff00000081,
-    0x7fffffff000000ff,
-    0x7fffffff00000100,
-    0x7fffffff00000200,
-    0x7fffffff000003e8,
-    0x7fffffff00000400,
-    0x7fffffff00001000,
-    0x7fffffff00007fff,
-    0x7fffffff00008000,
-    0x7fffffff00008001,
-    0x7fffffff0000ffff,
-    0x7fffffff00010000,
-    0x7fffffff05ffff05,
-    0x7fffffff7fffffff,
-    0x7fffffff80000000,
-    0x7fffffff80000001,
-    0x7fffffffffffffff,
-    0x8000000000000000,
-    0x8000000000000001,
-    0x8000000000000010,
-    0x8000000000000020,
-    0x8000000000000040,
-    0x8000000000000064,
-    0x800000000000007f,
-    0x8000000000000080,
-    0x8000000000000081,
-    0x80000000000000ff,
-    0x8000000000000100,
-    0x8000000000000200,
-    0x80000000000003e8,
-    0x8000000000000400,
-    0x8000000000001000,
-    0x8000000000007fff,
-    0x8000000000008000,
-    0x8000000000008001,
-    0x800000000000ffff,
-    0x8000000000010000,
-    0x8000000005ffff05,
-    0x800000007fffffff,
-    0x8000000080000000,
-    0x8000000080000001,
-    0x80000000ffffffff,
-    0x8000000100000000,
-    0x8000000100000001,
-    0x8000000100000010,
-    0x8000000100000020,
-    0x8000000100000040,
-    0x8000000100000064,
-    0x800000010000007f,
-    0x8000000100000080,
-    0x8000000100000081,
-    0x80000001000000ff,
-    0x8000000100000100,
-    0x8000000100000200,
-    0x80000001000003e8,
-    0x8000000100000400,
-    0x8000000100001000,
-    0x8000000100007fff,
-    0x8000000100008000,
-    0x8000000100008001,
-    0x800000010000ffff,
-    0x8000000100010000,
-    0x8000000105ffff05,
-    0x800000017fffffff,
-    0x8000000180000000,
-    0x8000000180000001,
-    0x80000001ffffffff,
-    0xffffffff00000000,
-    0xffffffff00000001,
-    0xffffffff00000010,
-    0xffffffff00000020,
-    0xffffffff00000040,
-    0xffffffff00000064,
-    0xffffffff0000007f,
-    0xffffffff00000080,
-    0xffffffff00000081,
-    0xffffffff000000ff,
-    0xffffffff00000100,
-    0xffffffff00000200,
-    0xffffffff000003e8,
-    0xffffffff00000400,
-    0xffffffff00001000,
-    0xffffffff00007fff,
-    0xffffffff00008000,
-    0xffffffff00008001,
-    0xffffffff0000ffff,
-    0xffffffff00010000,
-    0xffffffff05ffff05,
-    0xffffffff7fffffff,
-    0xffffffff80000000,
-    0xffffffff80000001,
-    0xfffffffffa0000fa,
-    0xffffffffffff7fff,
-    0xffffffffffff8000,
-    0xffffffffffff8001,
-    0xffffffffffffff7f,
-    0xffffffffffffff80,
-    0xffffffffffffff81,
-    0xffffffffffffffff,
-  ];
-}
diff --git a/runtime/tools/dartfuzz/gen_api_table.dart b/runtime/tools/dartfuzz/gen_api_table.dart
index e4a55d6..39593aa 100644
--- a/runtime/tools/dartfuzz/gen_api_table.dart
+++ b/runtime/tools/dartfuzz/gen_api_table.dart
@@ -18,9 +18,8 @@
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
 
-import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'gen_util.dart';
 
 // Class to represent a library method by name and prototype representation.
 class DartLib {
@@ -39,27 +38,7 @@
 var mapTable = <DartLib>[];
 
 main() async {
-  // Set paths. Note that for this particular use case, packageRoot can be
-  // any directory. Here, we set it to the top of the SDK development, and
-  // derive the required sdkPath from there.
-  final String packageRoot = Platform.environment['DART_TOP'];
-  if (packageRoot == null) {
-    throw StateError('No environment variable DART_TOP');
-  }
-  final sdkPath = '$packageRoot/tools/sdks/dart-sdk';
-
-  // This does most of the hard work of getting the analyzer configured
-  // correctly. Typically the included paths are the files and directories
-  // that need to be analyzed, but the SDK is always available, so it isn't
-  // really important for this particular use case. We use the implementation
-  // class in order to pass in the sdkPath directly.
-  final provider = PhysicalResourceProvider.INSTANCE;
-  final collection = AnalysisContextCollectionImpl(
-      includedPaths: <String>[packageRoot],
-      excludedPaths: <String>[packageRoot + "/pkg/front_end/test"],
-      resourceProvider: provider,
-      sdkPath: sdkPath);
-  final AnalysisSession session = collection.contexts[0].currentSession;
+  final AnalysisSession session = GenUtil.createAnalysisSession();
 
   // Visit libraries for table generation.
   await visitLibraryAtUri(session, 'dart:async');
@@ -312,6 +291,7 @@
 
 void dumpTable(String identifier, List<DartLib> table) {
   print('  static const $identifier = [');
+  table.sort((a, b) => a.name.compareTo(b.name));
   table.forEach((t) => print('    DartLib(\'${t.name}\', \'${t.proto}\'),'));
   print('  ];');
 }
diff --git a/runtime/tools/dartfuzz/gen_type_table.dart b/runtime/tools/dartfuzz/gen_type_table.dart
new file mode 100644
index 0000000..d6cbd3d
--- /dev/null
+++ b/runtime/tools/dartfuzz/gen_type_table.dart
@@ -0,0 +1,1349 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Generates the type tables used by DartFuzz.
+//
+// Usage:
+//   dart gen_type_table.dart > dartfuzz_type_table.dart
+//
+// Reformat:
+//   tools/sdks/dart-sdk/bin/dartfmt -w \
+//   runtime/tools/dartfuzz/dartfuzz_type_table.dart
+//
+// Then send out modified dartfuzz_type_table.dart for review together
+// with a modified dartfuzz.dart that increases the version.
+
+import 'dart:io';
+import 'dart:math';
+
+import 'package:args/args.dart';
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+import 'gen_util.dart';
+
+// Minimum number of operators that are required for a type to be included in
+// the type table.
+final int operatorCountThreshold = 2;
+
+//
+// Operators and functions.
+//
+
+// Map type to a list of constructors names with a list of constructor
+// parameter types.
+Map<String, Map<String, List<String>>> constructors =
+    new Map<String, Map<String, List<String>>>();
+
+// Map type to a list of assignment operators with a set of the
+// assignable right hand side types.
+Map<String, Map<String, Set<String>>> assignOps =
+    new Map<String, Map<String, Set<String>>>();
+
+// Map type to a list of binary operators with set of the respective
+// types for the first and second operand.
+Map<String, Map<String, Set<List<String>>>> binOps =
+    new Map<String, Map<String, Set<List<String>>>>();
+
+// Map type to a list of available unary operators.
+Map<String, Set<String>> uniOps = new Map<String, Set<String>>();
+
+//
+// Type grouping.
+//
+
+// All Set<E> types: SET_INT, SET_STRING, etc.
+Set<String> setTypes = new Set<String>();
+
+// All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
+Set<String> mapTypes = new Set<String>();
+
+// All List<E> types: LIST_INT, LIST_STRING, etc.
+Set<String> listTypes = new Set<String>();
+
+// All floating point types: DOUBLE, SET_DOUBLE, MAP_X_DOUBLE, etc.
+Set<String> fpTypes = new Set<String>();
+
+// All iterable types: Set types + List types.
+// These can be used in for(x in <iterable type>),
+// therefore Map is not included.
+Set<String> iterableTypes1 = new Set<String>();
+
+// All trivially indexable types: Map types and List types.
+// Elements of these can be written and read by [], unlike Set
+// which uses getElementAt to access individual elements
+Set<String> indexableTypes = new Set<String>();
+
+// Complex types: Collection types instantiated with nested argument
+// e.g Map<List<>, >.
+Set<String> complexTypes = new Set<String>();
+
+//
+// Type relations.
+//
+
+// Map type to the resulting type when subscripted.
+// Example: List<String> subscripts to String.
+Map<String, String> subscriptsTo = new Map<String, String>();
+
+// Map type to a Set of types that contain it as an element.
+// Example: String is element of List<String> and Map<int, String>
+Map<String, Set<String>> elementOf = new Map<String, Set<String>>();
+
+// Map type to a Set of types that contain it as an indexable element.
+// Same as element of, but without Set types.
+Map<String, Set<String>> indexableElementOf = new Map<String, Set<String>>();
+
+// Map type to type required as index.
+// Example: List<String> is indexed by int,
+// Map<String, double> indexed by String.
+Map<String, String> indexedBy = new Map<String, String>();
+
+//
+// Interface relationships.
+//
+
+// Map Interface type to Set of types that implement it.
+// Example: interface num is implemented by int and double.
+Map<String, Set<String>> interfaceRels = new Map<String, Set<String>>();
+
+// Convert analyzer's displayName to constant name used by dartfuzz.
+// Example: Set<int, String> -> SET_INT_STRING
+String getConstName(String displayName) {
+  String constName = displayName;
+  constName = constName.replaceAll('<', '_');
+  constName = constName.replaceAll('>', '');
+  constName = constName.replaceAll(', ', '_');
+  constName = constName.toUpperCase();
+  return constName;
+}
+
+// Returns true if the given type fails the filter criteria.
+bool shouldFilterType(String typName, {bool fp = true, bool flatTp = false}) {
+  if (!fp && fpTypes.contains(typName)) {
+    return true;
+  }
+  if (flatTp && complexTypes.contains(typName)) {
+    return true;
+  }
+  return false;
+}
+
+// Returns true if any of the paramters in the list fails the
+// filter criteria.
+bool shouldFilterParameterList(List<String> parameters,
+    {bool fp = true, bool flatTp = false}) {
+  for (String parameter in parameters) {
+    if (shouldFilterType(parameter, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Filter a set of a list of parameters according to their type.
+// A paramter list is only retained if all of the contained paramters
+// pass the filter criteria.
+Set<List<String>> filterParameterList(Set<List<String>> parameterList,
+    {bool fp = true, bool flatTp = false}) {
+  Set<List<String>> filteredParams = <List<String>>{};
+  for (List<String> parameters in parameterList) {
+    if (!shouldFilterParameterList(parameters, fp: fp, flatTp: flatTp)) {
+      filteredParams.add(parameters);
+    }
+  }
+  return filteredParams;
+}
+
+// Filter a set of parameters according to their type.
+Set<String> filterParameterSet(Set<String> parameterSet,
+    {bool fp = true, bool flatTp = false}) {
+  Set<String> filteredParams = <String>{};
+  for (String parameter in parameterSet) {
+    if (!shouldFilterType(parameter, fp: fp, flatTp: flatTp)) {
+      filteredParams.add(parameter);
+    }
+  }
+  return filteredParams;
+}
+
+// Filter map of operators to a set of a list of parameter types
+// as used for binary operators.
+Map<String, Set<List<String>>> filterOperatorMapSetList(
+    Map<String, Set<List<String>>> operators,
+    {bool fp = true,
+    bool flatTp = false}) {
+  Map<String, Set<List<String>>> filteredOps = <String, Set<List<String>>>{};
+  operators.forEach((op, parameterList) {
+    Set<List<String>> filteredParams =
+        filterParameterList(parameterList, fp: fp, flatTp: flatTp);
+    if (filteredParams.isNotEmpty) {
+      filteredOps[op] = filteredParams;
+    }
+  });
+  return filteredOps;
+}
+
+// Filter map of operators to a List of parameter types as used for
+// constructors.
+Map<String, List<String>> filterOperatorMapList(
+    Map<String, List<String>> operators,
+    {bool fp = true,
+    bool flatTp = false}) {
+  Map<String, List<String>> filteredOps = <String, List<String>>{};
+  operators.forEach((op, parameterList) {
+    if (!shouldFilterParameterList(parameterList, fp: fp, flatTp: flatTp)) {
+      filteredOps[op] = parameterList;
+    }
+  });
+  return filteredOps;
+}
+
+// Filter map of operators to a set of rhs types as used for assignment
+// operators.
+Map<String, Set<String>> filterOperatorMapSet(
+    Map<String, Set<String>> operators,
+    {bool fp = true,
+    bool flatTp = false}) {
+  Map<String, Set<String>> filteredOps = <String, Set<String>>{};
+  operators.forEach((op, parameterSet) {
+    Set<String> filteredParams =
+        filterParameterSet(parameterSet, fp: fp, flatTp: flatTp);
+    if (filteredParams.isNotEmpty) {
+      filteredOps[op] = filteredParams;
+    }
+  });
+  return filteredOps;
+}
+
+// Filter map of type to map of operators as used for binary operators.
+Map<String, Map<String, Set<List<String>>>> filterTypesMap4(
+    Map<String, Map<String, Set<List<String>>>> types,
+    {bool fp = true,
+    bool flatTp = false}) {
+  Map<String, Map<String, Set<List<String>>>> filteredTypes =
+      <String, Map<String, Set<List<String>>>>{};
+  types.forEach((baseType, ops) {
+    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    Map<String, Set<List<String>>> filteredOps =
+        filterOperatorMapSetList(ops, fp: fp, flatTp: flatTp);
+    if (filteredOps.isNotEmpty) {
+      filteredTypes[baseType] = filteredOps;
+    }
+  });
+  return filteredTypes;
+}
+
+// Print map of type to map of operators as used for binary operators.
+void printTypeMap4(
+    String name, Map<String, Map<String, Set<List<String>>>> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  print("  static const Map<DartType, Map<String, " +
+      "Set<List<DartType>>>> ${name} = {");
+  Map<String, Map<String, Set<List<String>>>> filteredTypes =
+      filterTypesMap4(types, fp: fp, flatTp: flatTp);
+  for (var baseType in filteredTypes.keys.toList()..sort()) {
+    var ops = filteredTypes[baseType];
+    print("    ${prefix}${baseType}: {");
+    for (var op in ops.keys.toList()..sort()) {
+      var paramTypeL = ops[op];
+      print("      '${op}': {");
+      for (var paramTypes in paramTypeL) {
+        stdout.write("          [");
+        for (String paramType in paramTypes) {
+          stdout.write("${prefix}${paramType}, ");
+        }
+        print("],");
+      }
+      print("        },");
+    }
+    print("    },");
+  }
+  print("  };");
+}
+
+// Filter map of type to map of operators as used for assignment operators.
+Map<String, Map<String, Set<String>>> filterTypesMap3Set(
+    Map<String, Map<String, Set<String>>> types,
+    {bool fp = true,
+    bool flatTp = false}) {
+  Map<String, Map<String, Set<String>>> filteredTypes =
+      <String, Map<String, Set<String>>>{};
+  types.forEach((baseType, ops) {
+    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    Map<String, Set<String>> filteredOps =
+        filterOperatorMapSet(ops, fp: fp, flatTp: flatTp);
+    if (filteredOps.isNotEmpty) {
+      filteredTypes[baseType] = filteredOps;
+    }
+  });
+  return filteredTypes;
+}
+
+// Print map of type to map of operators as used for assignment operators.
+void printTypeMap3Set(String name, Map<String, Map<String, Set<String>>> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  print("  static const Map<DartType, " +
+      "Map<String, Set<DartType>>> ${name} = {");
+
+  Map<String, Map<String, Set<String>>> filteredTypes =
+      filterTypesMap3Set(types, fp: fp, flatTp: flatTp);
+  for (var baseType in filteredTypes.keys.toList()..sort()) {
+    var ops = filteredTypes[baseType];
+    print("    ${prefix}${baseType}: {");
+    for (var op in ops.keys.toList()) {
+      var paramTypes = ops[op];
+      stdout.write("      '${op}': {");
+      for (String paramType in paramTypes.toList()..sort()) {
+        stdout.write("${prefix}${paramType}, ");
+      }
+      print("}, ");
+    }
+    print("    },");
+  }
+  print("  };");
+}
+
+// Filter map of type to map of operators as used for constructors.
+Map<String, Map<String, List<String>>> filterTypesMap3(
+    Map<String, Map<String, List<String>>> types,
+    {bool fp = true,
+    bool flatTp = false}) {
+  Map<String, Map<String, List<String>>> filteredTypes =
+      <String, Map<String, List<String>>>{};
+  types.forEach((baseType, ops) {
+    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    Map<String, List<String>> filteredOps =
+        filterOperatorMapList(ops, fp: fp, flatTp: flatTp);
+    if (filteredOps.isNotEmpty) {
+      filteredTypes[baseType] = filteredOps;
+    }
+  });
+  return filteredTypes;
+}
+
+// Print map of type to map of operators as used for constructors.
+void printTypeMap3(String name, Map<String, Map<String, List<String>>> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  print("  static const Map<DartType, Map<String, " +
+      "List<DartType>>> ${name} = {");
+  var filteredTypes = filterTypesMap3(types, fp: fp, flatTp: flatTp);
+  for (var baseType in filteredTypes.keys.toList()..sort()) {
+    var ops = filteredTypes[baseType];
+    print("    ${prefix}${baseType}: {");
+    for (var op in ops.keys.toList()..sort()) {
+      var paramTypes = ops[op];
+      stdout.write("      '${op}': [");
+      for (String paramType in paramTypes.toList()..sort()) {
+        stdout.write("${prefix}${paramType}, ");
+      }
+      print("], ");
+    }
+    print("    },");
+  }
+  print("  };");
+}
+
+// Filter map of type collection name to set of types.
+Map<String, Set<String>> filterTypesMap2(Map<String, Set<String>> types,
+    {bool fp = true, bool flatTp = false}) {
+  Map<String, Set<String>> filteredTypes = <String, Set<String>>{};
+  types.forEach((baseType, parameterSet) {
+    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    Set<String> filteredParams =
+        filterParameterSet(parameterSet, fp: fp, flatTp: flatTp);
+    if (filteredParams.isNotEmpty) {
+      filteredTypes[baseType] = filteredParams;
+    }
+  });
+  return filteredTypes;
+}
+
+// Print map of type collection name to set of types.
+void printTypeMap2(String name, Map<String, Set<String>> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  print("  static const Map<DartType, Set<DartType>> ${name} = {");
+  var filteredTypes = filterTypesMap2(types, fp: fp, flatTp: flatTp);
+  for (var baseType in filteredTypes.keys.toList()..sort()) {
+    var paramTypes = filteredTypes[baseType];
+    stdout.write("    ${prefix}${baseType}: { ");
+    for (String paramType in paramTypes.toList()..sort()) {
+      stdout.write("${prefix}${paramType}, ");
+    }
+    print("},");
+  }
+  print("  };");
+}
+
+// Filter map of type to type.
+Map<String, String> filterTypesMap1(Map<String, String> types,
+    {bool fp = true, bool flatTp = false}) {
+  Map<String, String> filteredTypes = <String, String>{};
+  types.forEach((baseType, paramType) {
+    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    if (shouldFilterType(paramType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    filteredTypes[baseType] = paramType;
+  });
+  return filteredTypes;
+}
+
+// Print map of type to type.
+void printTypeMap1(String name, Map<String, String> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  print("  static const Map<DartType, DartType> ${name} = {");
+  var filteredTypes = filterTypesMap1(types, fp: fp, flatTp: flatTp);
+  for (var baseType in filteredTypes.keys.toList()..sort()) {
+    var paramType = filteredTypes[baseType];
+    print("    ${prefix}"
+        "${baseType}: ${prefix}${paramType}, ");
+  }
+  print("  };");
+}
+
+// Filter set of types.
+Set<String> filterTypesSet(Set<String> choices,
+    {bool fp = true, bool flatTp = false}) {
+  Set<String> filteredTypes = {};
+  filteredTypes.addAll(choices);
+  if (!fp) {
+    filteredTypes = filteredTypes.difference(fpTypes);
+  }
+  if (flatTp) {
+    filteredTypes = filteredTypes.difference(complexTypes);
+  }
+  return filteredTypes;
+}
+
+// Print set of types.
+void printTypeSet(String name, Set<String> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  stdout.write("  static const Set<DartType> ${name} = {");
+  for (String typName in filterTypesSet(types, fp: fp, flatTp: flatTp).toList()
+    ..sort()) {
+    stdout.write("${prefix}$typName, ");
+  }
+  print("};");
+}
+
+// Filter map to type to set of operators as used for unitary operators.
+Map<String, Set<String>> filterTypeMapSet(Map<String, Set<String>> types,
+    {bool fp = true, bool flatTp = false}) {
+  Map<String, Set<String>> filteredTypes = <String, Set<String>>{};
+  types.forEach((baseType, params) {
+    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
+      return true;
+    }
+    filteredTypes[baseType] = params;
+  });
+  return filteredTypes;
+}
+
+// Print map to type to set of operators as used for unitary operators.
+void printTypeMapSet(String name, Map<String, Set<String>> types,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  final String prefix = "${subclass ? "DartType." : ""}";
+  print("  static const Map<DartType, Set<String>> $name = {");
+  var filteredTypes = filterTypeMapSet(types, fp: fp, flatTp: flatTp);
+  for (var baseType in filteredTypes.keys.toList()..sort()) {
+    var paramTypes = filteredTypes[baseType].toList()..sort();
+    print("    ${prefix}${baseType}: {" + paramTypes.join(", ") + "},");
+  }
+  print("  };");
+}
+
+// Print all generated and collected types, operators and type collections.
+void printTypeTable(Set<InterfaceType> allTypes,
+    {bool fp = true, bool flatTp = false}) {
+  final bool subclass = !fp || flatTp;
+  if (!subclass) {
+    print("""
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Class that represents some common Dart types.
+///
+/// NOTE: this code has been generated automatically.
+///""");
+  }
+
+  String className = 'DartType${fp ? "" : "NoFp"}${flatTp ? "FlatTp" : ""}';
+
+  print('class $className'
+      '${subclass ? " extends DartType" : ""} {');
+  print("  final String name;");
+  if (!subclass) {
+    print("  const DartType._withName(this.name);");
+    print("""
+  factory $className.fromDartConfig(
+      {bool enableFp = false, bool disableNesting =
+    false}) {
+    if (enableFp && !disableNesting) {
+      return DartType();
+    } else if (!enableFp && !disableNesting) {
+      return DartTypeNoFp();
+    } else if (enableFp && disableNesting) {
+      return DartTypeFlatTp();
+    } else {
+      return DartTypeNoFpFlatTp();
+    }
+  }""");
+  } else {
+    print('  const $className'
+        '._withName(this.name) : super._withName(name);');
+  }
+
+  print("""
+  const $className() : name = null;
+  static bool isListType(DartType tp) {
+    return DartType._listTypes.contains(tp);
+  }
+
+  static bool isMapType(DartType tp) {
+    return DartType._mapTypes.contains(tp);
+  }
+
+  static bool isCollectionType(DartType tp) {
+    return DartType._collectionTypes.contains(tp);
+  }
+
+  static bool isGrowableType(DartType tp) {
+    return DartType._growableTypes.contains(tp);
+  }
+
+  static bool isComplexType(DartType tp) {
+    return DartType._complexTypes.contains(tp);
+  }
+
+  bool isInterfaceOfType(DartType tp, DartType iTp) {
+    return _interfaceRels.containsKey(iTp) && _interfaceRels[iTp].contains(tp);
+  }
+
+  Set<DartType> get mapTypes {
+    return _mapTypes;
+  }
+
+  bool isSpecializable(DartType tp) {
+    return _interfaceRels.containsKey(tp);
+  }
+
+  Set<DartType> interfaces(DartType tp) {
+    if (_interfaceRels.containsKey(tp)) {
+      return _interfaceRels[tp];
+    }
+    return null;
+  }
+
+  DartType indexType(DartType tp) {
+    if (_indexedBy.containsKey(tp)) {
+      return _indexedBy[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> indexableElementTypes(DartType tp) {
+    if (_indexableElementOf.containsKey(tp)) {
+      return _indexableElementOf[tp];
+    }
+    return null;
+  }
+
+  bool isIndexableElementType(DartType tp) {
+    return _indexableElementOf.containsKey(tp);
+  }
+
+  DartType elementType(DartType tp) {
+    if (_subscriptsTo.containsKey(tp)) {
+      return _subscriptsTo[tp];
+    }
+    return null;
+  }
+
+  Set<DartType> get iterableTypes1 {
+    return _iterableTypes1;
+  }
+
+  Set<String> uniOps(DartType tp) {
+    if (_uniOps.containsKey(tp)) {
+      return _uniOps[tp];
+    }
+    return <String>{};
+  }
+
+  Set<String> binOps(DartType tp) {
+    if (_binOps.containsKey(tp)) {
+      return _binOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<List<DartType>> binOpParameters(DartType tp, String op) {
+    if (_binOps.containsKey(tp) &&
+        _binOps[tp].containsKey(op)) {
+      return _binOps[tp][op];
+    }
+    return null;
+  }
+
+  Set<String> assignOps(DartType tp) {
+    if (_assignOps.containsKey(tp)) {
+      return _assignOps[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  Set<DartType> assignOpRhs(DartType tp, String op) {
+    if (_assignOps.containsKey(tp) &&
+        _assignOps[tp].containsKey(op)) {
+      return _assignOps[tp][op];
+    }
+    return <DartType>{};
+  }
+
+  bool hasConstructor(DartType tp) {
+    return _constructors.containsKey(tp);
+  }
+
+  Set<String> constructors(DartType tp) {
+    if (_constructors.containsKey(tp)) {
+      return _constructors[tp].keys.toSet();
+    }
+    return <String>{};
+  }
+
+  List<DartType> constructorParameters(DartType tp, String constructor) {
+    if (_constructors.containsKey(tp) &&
+        _constructors[tp].containsKey(constructor)) {
+      return _constructors[tp][constructor];
+    }
+    return null;
+  }
+
+  Set<DartType> get allTypes {
+    return _allTypes;
+  }
+
+""");
+
+  Set<String> instTypes = {};
+
+  // Generate one static DartType instance for all instantiable types.
+  // TODO (felih): maybe add void type?
+  allTypes.forEach((baseType) {
+    String constName = getConstName(baseType.displayName);
+    instTypes.add(constName);
+    if (!subclass) {
+      print("  static const ${constName} = const " +
+          "DartType._withName(\"${baseType.displayName}\");");
+    }
+  });
+
+  if (!subclass) {
+    // Generate one static DartType instance for all non instantiable types.
+    // These are required to resolve interface relations, but should not be
+    // used directly to generate dart programs.
+    print("");
+    print("  // NON INSTANTIABLE" "");
+    interfaceRels.keys.forEach((constName) {
+      if (instTypes.contains(constName)) return true;
+      print("  static const ${constName} = const " +
+          "DartType._withName(\"__${constName}\");");
+    });
+  }
+
+  // Generate a list of all instantiable types.
+  print("");
+  print("""
+  // All types extracted from analyzer.
+  static const _allTypes = {""");
+  filterTypesSet(instTypes, fp: fp, flatTp: flatTp).forEach((constName) {
+    print("    ${subclass ? "DartType." : ""}${constName},");
+  });
+  print("  };");
+
+  print("");
+  print("""
+  // All List<E> types: LIST_INT, LIST_STRING, etc.""");
+  printTypeSet("_listTypes", listTypes, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // All Set types: SET_INT, SET_STRING, etc.""");
+  printTypeSet("_setTypes", setTypes, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.""");
+  printTypeSet("_mapTypes", mapTypes, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // All collection types: list, map and set types.""");
+  printTypeSet("_collectionTypes", {...listTypes, ...setTypes, ...mapTypes},
+      fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // All growable types: list, map, set and string types.""");
+  printTypeSet(
+      "_growableTypes", {...listTypes, ...setTypes, ...mapTypes, 'STRING'},
+      fp: fp, flatTp: flatTp);
+
+  if (!subclass) {
+    print("");
+    print(
+        "  // All floating point types: DOUBLE, SET_DOUBLE, MAP_X_DOUBLE, etc.");
+    printTypeSet("_fpTypes", fpTypes);
+  }
+
+  print("");
+  print("""
+  // All trivially indexable types: Map types and List types.
+  // Elements of these can be written and read by [], unlike Set
+  // which uses getElementAt to access individual elements.""");
+  printTypeSet("_indexableTypes", indexableTypes, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to the resulting type when subscripted.
+  // Example: List<String> subscripts to String.""");
+  printTypeMap1("_subscriptsTo", subscriptsTo, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to type required as index.
+  // Example: List<String> is indexed by int,
+  // Map<String, double> indexed by String.""");
+  printTypeMap1("_indexedBy", indexedBy, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to a Set of types that contain it as an element.
+  // Example: String is element of List<String> and Map<int, String>""");
+  printTypeMap2("_elementOf", elementOf, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to a Set of types that contain it as an indexable element.
+  // Same as element of, but without Set types.""");
+  printTypeMap2("_indexableElementOf", indexableElementOf,
+      fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // All iterable types: Set types + List types.
+  // These can be used in for(x in <iterable type>),
+  // therefore Map is not included.""");
+  printTypeSet("_iterableTypes1", iterableTypes1, fp: fp, flatTp: flatTp);
+
+  if (!subclass) {
+    print("");
+    print("""
+  // Complex types: Collection types instantiated with nested argument
+  // e.g Map<List<>, >.""");
+    printTypeSet("_complexTypes", complexTypes);
+  }
+
+  print("");
+  print("""
+  // Map Interface type to Set of types that implement it.
+  // Example: interface num is implemented by int and double.""");
+  printTypeMap2("_interfaceRels", interfaceRels, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to a list of constructors names with a list of constructor
+  // parameter types.""");
+  printTypeMap3("_constructors", constructors, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to a list of binary operators with set of the respective
+  // types for the first and second operand.""");
+  printTypeMap4("_binOps", binOps, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to a list of available unary operators.""");
+  printTypeMapSet("_uniOps", uniOps, fp: fp, flatTp: flatTp);
+
+  print("");
+  print("""
+  // Map type to a list of assignment operators with a set of the
+  // assignable right hand side types.""");
+  printTypeMap3Set("_assignOps", assignOps, fp: fp, flatTp: flatTp);
+
+  print("}");
+  print("");
+}
+
+// Returns true if type can be set and get via [].
+bool isIndexable(InterfaceType tp) {
+  bool isIndexable = false;
+  for (var method in tp.methods) {
+    if (method.name == "[]") {
+      isIndexable = true;
+      break;
+    }
+  }
+  return isIndexable;
+}
+
+// Returns true if iTypeName == typeName or if
+// iTypeName is an interface type that is implemented by typeName.
+// List<int> is interface of Int8List
+bool isInterfaceOf(String iTypName, String typName) {
+  return iTypName == typName ||
+      (interfaceRels.containsKey(iTypName) &&
+          interfaceRels[iTypName].contains(typName));
+}
+
+// Filter operator parameters so that the more specific types are discarded if
+// the respective interface type is already in the list.
+// This is required not only to give each parameter type equal probability but
+// also so that dartfuzz can efficiently filter floating point types from the
+// interface relations.
+Set<List<String>> filterOperator(Set<List<String>> op) {
+  Set<List<String>> newOp = new Set<List<String>>();
+  if (op.length < 2) return op;
+  for (List<String> params1 in op) {
+    bool keep = false;
+    for (List<String> params2 in op) {
+      for (int k = 0; k < params1.length; ++k) {
+        if (!isInterfaceOf(params2[k], params1[k])) {
+          keep = true;
+          break;
+        }
+      }
+      if (keep) break;
+    }
+    if (keep) {
+      newOp.add(params1);
+    }
+  }
+  return newOp;
+}
+
+// See comment on filterOpterator.
+void filterOperators(Set<InterfaceType> allTypes) {
+  for (InterfaceType tp in allTypes) {
+    String typName = getConstName(tp.displayName);
+    if (!binOps.containsKey(typName)) continue;
+    for (String op in binOps[typName].keys) {
+      binOps[typName][op] = filterOperator(binOps[typName][op]);
+    }
+  }
+}
+
+// Extract all binary and unary operators for tp.
+// Operators are stored by return type in the following way:
+// return type: { operator: { parameter types } }
+// Example: bool: { == : { [int, int], [double, double] }}
+//          int: {'~', '-'},
+// Does not recurse into interfaces and superclasses of tp.
+void getOperatorsForTyp(String typName, InterfaceType tp, fromLiteral) {
+  for (MethodElement method in tp.methods) {
+    // Detect whether tp can be parsed from a literal (dartfuzz.dart can
+    // already handle that).
+    // This is usually indicated by the presence of the static constructor
+    // 'castFrom' or 'parse'.
+    if (method.isStatic &&
+        (method.name == 'castFrom' || method.name == 'parse')) {
+      fromLiteral.add(getConstName(tp.displayName));
+    }
+    // Hack: dartfuzz.dart already handles subscripts, therefore we exclude
+    // them from the generated type table.
+    if (method.name.startsWith('[]')) continue;
+    if (method.isOperator) {
+      // TODO (felih): Include support for type 'dynamic'.
+      bool skip = false;
+      for (var p in method.parameters) {
+        if (getConstName(p.type.displayName) == 'DYNAMIC') {
+          skip = true;
+          break;
+        }
+      }
+      if (skip) continue;
+      if (method.parameters.length == 1) {
+        // Get binary operators.
+
+        String retTypName = getConstName(method.returnType.displayName);
+        binOps[retTypName] ??= new Map<String, Set<List<String>>>();
+        binOps[retTypName][method.name] ??= new Set<List<String>>();
+
+        String rhsTypName = getConstName(method.parameters[0].type.displayName);
+
+        // TODO (felih): no hashing for List<String> ?
+        // if i remove this test i will get duplicates even though it is a Set.
+        bool present = false;
+        for (List<String> o in binOps[retTypName][method.name]) {
+          if (o[0] == typName && o[1] == rhsTypName) {
+            present = true;
+            break;
+          }
+        }
+        if (!present)
+          binOps[retTypName][method.name].add([typName, rhsTypName]);
+
+        // Add some assignment operators corresponding to the binary operators.
+        // Example: for '+' add '+='.
+        // Bool types have to be filtered because boolean binary operators
+        // can not be used to derive assignment operators in this way, e.g.
+        // <= is not a valid assignment operator for bool types.
+        if (retTypName != 'BOOL') {
+          assignOps[retTypName] ??= new Map<String, Set<String>>();
+          String ao = method.name + '=';
+          assignOps[retTypName][ao] ??= new Set<String>();
+          assignOps[retTypName][ao].add(rhsTypName);
+        }
+      } else {
+        // Get unary operators.
+        uniOps[typName] ??= new Set<String>();
+        String uo = method.name;
+        // Hack: remove unary from operator so that the operator name can be
+        // used directly for source code generation.
+        if (uo.startsWith('unary')) uo = '-';
+        uniOps[typName].add('\'$uo\'');
+      }
+    }
+  }
+}
+
+// Extract all binary and unary operators for all types.
+void getOperators(Set<InterfaceType> allTypes) {
+  // Set of types that can be constructed directly from literals and do
+  // not need special constructors (e.g. List<int> = [1, 2] as opposed to
+  // Int8List int8list = Int8List.fromList([1, 2]) ).
+  Set<String> fromLiteral = new Set<String>();
+
+  // getOperatorsForTyp uses a heuristic to detect which types can be
+  // constructed from a literal, but the heuristic misses the String type
+  // so we have to add it manually.
+  fromLiteral.add('STRING');
+  // Get binary, unary and assignment operators.
+  for (InterfaceType tp in allTypes) {
+    String typName = getConstName(tp.displayName);
+    // Manually add basic assignment operators which each type supports.
+    assignOps[typName] ??= new Map<String, Set<String>>();
+    assignOps[typName]['='] = {typName};
+    assignOps[typName]['??='] = {typName};
+    getOperatorsForTyp(typName, tp, fromLiteral);
+  }
+
+  // Add some static ops not extractable from dart:core/typed_data.
+  for (String typName in binOps.keys) {
+    binOps[typName] ??= new Map<String, Set<List<String>>>();
+    binOps[typName]['??'] = {
+      [typName, typName],
+    };
+  }
+  binOps['BOOL'] ??= new Map<String, Set<List<String>>>();
+  binOps['BOOL']['&&'] = {
+    ['BOOL', 'BOOL'],
+  };
+  binOps['BOOL']['||'] = {
+    ['BOOL', 'BOOL'],
+  };
+  uniOps['BOOL'] ??= new Set<String>();
+  uniOps['BOOL'].add('\'!\'');
+
+  // Get constructors.
+  for (InterfaceType tp in allTypes) {
+    String typName = getConstName(tp.displayName);
+    // Skip types that are constructable from a literal.
+    if (fromLiteral.contains(typName)) {
+      continue;
+    }
+    for (ConstructorElement constructor in tp.constructors) {
+      if (constructor.name.startsWith('_')) continue;
+      List<String> params = new List<String>();
+      bool canConstruct = true;
+      for (var p in constructor.parameters) {
+        String tstr = getConstName(p.type.displayName);
+        // Only allow trivially constructable parameters. If a constructor
+        // parameter is not constructable from a literal, skip the constructor.
+        if (!fromLiteral.contains(tstr)) {
+          canConstruct = false;
+          break;
+        }
+        // Only add positional required parameters.
+        // TODO (felih): include named and optional parameters.
+        if (!p.isNamed) params.add(tstr);
+      }
+      if (!canConstruct) continue;
+
+      constructors[typName] ??= new Map<String, List<String>>();
+      constructors[typName][constructor.name] = params;
+    }
+  }
+  // Removed redundant specialized parameter types.
+  // E.g. if num is already contained remove bool and int.
+  filterOperators(allTypes);
+}
+
+// Analyze types to extract element and subscript relations
+// as well as precision type attributes.
+void analyzeTypes(Set<InterfaceType> allTypes) {
+  // Extract basic floating point types.
+  for (InterfaceType tp in allTypes) {
+    if (tp.displayName.contains('Float') ||
+        tp.displayName.contains('float') ||
+        tp.displayName.contains('double') ||
+        tp.displayName.contains('Double'))
+      fpTypes.add(getConstName(tp.displayName));
+  }
+
+  // Analyze all types to extract information useful for dart code generation.
+  for (InterfaceType tp in allTypes) {
+    final typName = getConstName(tp.displayName);
+
+    // Find topmost interface type, e.g. List<int> is interface for Int8List.
+    InterfaceType iTyp = tp;
+    while (iTyp.typeArguments.isEmpty && !iTyp.interfaces.isEmpty) {
+      iTyp = tp.interfaces[0];
+    }
+
+    // Group current type with their respective type group.
+    if (iTyp.name == "Set") setTypes.add(typName);
+    if (iTyp.name == "List") listTypes.add(typName);
+    if (iTyp.name == "Map") mapTypes.add(typName);
+
+    if (iTyp.typeArguments.length == 1) {
+      // Analyze Array, List and Set types.
+      String argName = getConstName(iTyp.typeArguments[0].displayName);
+      subscriptsTo[typName] = argName;
+      elementOf[argName] ??= new Set<String>();
+      elementOf[argName].add(typName);
+      if (isIndexable(iTyp)) {
+        indexableElementOf[argName] ??= new Set<String>();
+        indexableElementOf[argName].add(typName);
+        indexedBy[typName] = 'INT';
+        indexableTypes.add(typName);
+      }
+      // Check if type is floating point precision.
+      if (fpTypes.contains(typName) || fpTypes.contains(argName)) {
+        fpTypes.add(typName);
+      }
+    } else if (iTyp.typeArguments.length == 2) {
+      // Analyze Map types.
+      String argName0 = getConstName(iTyp.typeArguments[0].displayName);
+      String argName1 = getConstName(iTyp.typeArguments[1].displayName);
+      subscriptsTo[typName] = argName1;
+      elementOf[argName1] ??= new Set<String>();
+      elementOf[argName1].add(typName);
+      indexableElementOf[argName1] ??= new Set<String>();
+      indexableElementOf[argName1].add(typName);
+      indexedBy[typName] = argName0;
+      indexableTypes.add(typName);
+      // Check if type is floating point precision.
+      if (fpTypes.contains(typName) ||
+          fpTypes.contains(argName0) ||
+          fpTypes.contains(argName1)) {
+        fpTypes.add(typName);
+      }
+    }
+  }
+}
+
+// Split types into sets of types with none, one and two parameters
+// respectively.
+void getParameterizedTypes(
+    Set<InterfaceType> allTypes, // Set of all types.
+    Set<InterfaceType> pTypes1, // Out: types with one parameter e.g. List.
+    Set<InterfaceType> pTypes2, // Out: types with two parameters e.g. Map.
+    Set<InterfaceType> iTypes) {
+  // Out: types with no parameters.
+  for (var tp in allTypes) {
+    if (tp.typeArguments.length == 1 && tp.typeArguments[0].name == 'E')
+      pTypes1.add(tp);
+    else if (tp.typeArguments.length == 2 &&
+        tp.typeArguments[0].name == 'K' &&
+        tp.typeArguments[1].name == 'V')
+      pTypes2.add(tp);
+    else
+      iTypes.add(tp);
+  }
+}
+
+// Generate new types by instantiating types with one and two parameters
+// with the types having no parameters (or the parameters of which have
+// already been instantiated).
+// There will be no more then maxNew types generated.
+Set<InterfaceType> instantiatePTypes(
+    Set<InterfaceType> pTypes1, // Types with one parameter.
+    Set<InterfaceType> pTypes2, // Types with two parameters.
+    Set<InterfaceType> iTypes, // Types with no parameters.
+    {double maxNew = 64.0}) {
+  // Maximum number of newly generated types.
+  Set<InterfaceType> newITypes = new Set<InterfaceType>();
+
+  // Calculate the total number of new types if all combinations were used.
+  int nNew = pTypes1.length * iTypes.length +
+      pTypes2.length * iTypes.length * iTypes.length;
+  // Calculate how many generated types have to be skipped in order to stay
+  // under the maximum number set for generating new types (maxNew).
+  double step = maxNew / nNew;
+  double cntr = 0.0;
+
+  // Instantiate List and Set types.
+  pTypes1.forEach((pType) {
+    iTypes.forEach((iType) {
+      cntr += step;
+      if (cntr >= 1.0) {
+        cntr -= 1.0;
+      } else {
+        return true;
+      }
+      ParameterizedType ptx = pType.instantiate([iType]);
+      newITypes.add(ptx);
+      if (iType.typeArguments.length >= 1) {
+        complexTypes.add(getConstName(ptx.displayName));
+      }
+    });
+  });
+
+  // Instantiate Map types.
+  pTypes2.forEach((pType) {
+    iTypes.forEach((iType1) {
+      iTypes.forEach((iType2) {
+        cntr += step;
+        if (cntr >= 1.0) {
+          cntr -= 1.0;
+        } else {
+          return true;
+        }
+        ParameterizedType ptx = pType.instantiate([iType1, iType2]);
+        newITypes.add(ptx);
+        if (iType1.typeArguments.length >= 1 ||
+            iType2.typeArguments.length >= 1) {
+          complexTypes.add(getConstName(ptx.displayName));
+        }
+      });
+    });
+  });
+
+  // Add instantiated types to the set of types with no free parameters.
+  return iTypes.union(newITypes);
+}
+
+Set<InterfaceType> instantiateAllTypes(
+    Set<InterfaceType> allTypes, Set<String> iTypeFilter, int depth,
+    {double maxNew = 64.0}) {
+  // Types with one parameter (List, Set).
+  Set<InterfaceType> pTypes1 = new Set<InterfaceType>();
+  // Types with two parameters (Map).
+  Set<InterfaceType> pTypes2 = new Set<InterfaceType>();
+  // Types with no parameters or parameters of which have already been
+  // instantiated.
+  Set<InterfaceType> iTypes = new Set<InterfaceType>();
+  // Fill type sets with respective parameter types.
+  getParameterizedTypes(allTypes, pTypes1, pTypes2, iTypes);
+
+  // Filter the list of zero parameter types to exclude
+  // complex types like Int8List.
+  Set<InterfaceType> filteredITypes = {};
+  for (var iType in iTypes) {
+    if (iTypeFilter.contains(iType.displayName)) {
+      filteredITypes.add(iType);
+    }
+  }
+
+  // Instantiate types with one or two free parameters.
+  // Concatenate the newly instantiated types with the previous set of
+  // instantiated or zero parameter types to be used as input for the next
+  // round or instantiation.
+  // Each iteration constructs more nested types like
+  // Map<Map<int, int>, List<int>>.
+  for (int i = 0; i < depth + 1; ++i) {
+    double mn = max(1, maxNew / (depth + 1));
+    filteredITypes = filteredITypes
+        .union(instantiatePTypes(pTypes1, pTypes2, filteredITypes, maxNew: mn));
+  }
+  // Return list of instantiated types.
+  return iTypes.union(filteredITypes);
+}
+
+// Heuristic of which types to include:
+// count the number of operators and
+// check if the type can be constructed from a literal.
+int countOperators(ClassElement ce) {
+  int no = 0;
+  ce.methods.forEach((method) {
+    if (method.isOperator) {
+      no++;
+    }
+    // Detect whether type can be parsed from a literal (dartfuzz.dart can
+    // already handle that).
+    // This is usually indicated by the presence of the static constructor
+    // 'castFrom' or 'parse'.
+    if (method.isStatic &&
+        (method.name == 'castFrom' || method.name == 'parse')) {
+      no += 100;
+    }
+    for (InterfaceType ci in ce.interfaces) {
+      no += countOperators(ci.element);
+    }
+  });
+  return no;
+}
+
+// Analyze typed_data and core libraries to extract data types.
+void getDataTypes(Set<InterfaceType> allTypes, String dartTop) async {
+  final AnalysisSession session = GenUtil.createAnalysisSession(dartTop);
+
+  // Visit libraries for type table generation.
+  await visitLibraryAtUri(session, 'dart:typed_data', allTypes);
+  await visitLibraryAtUri(session, 'dart:core', allTypes);
+}
+
+visitLibraryAtUri(
+    AnalysisSession session, String uri, Set<InterfaceType> allTypes) async {
+  String libPath = session.uriConverter.uriToPath(Uri.parse(uri));
+  ResolvedLibraryResult result = await session.getResolvedLibrary(libPath);
+  if (result.state != ResultState.VALID) {
+    throw new StateError('Unable to resolve "$uri"');
+  }
+  visitLibrary(result.element, allTypes);
+}
+
+visitLibrary(LibraryElement library, Set<InterfaceType> allTypes) async {
+  // This uses the element model to traverse the code. The element model
+  // represents the semantic structure of the code. A library consists of
+  // one or more compilation units.
+  for (CompilationUnitElement unit in library.units) {
+    visitCompilationUnit(unit, allTypes);
+  }
+}
+
+visitCompilationUnit(CompilationUnitElement unit, Set<InterfaceType> allTypes) {
+  // Each compilation unit contains elements for all of the top-level
+  // declarations in a single file, such as variables, functions, and
+  // classes. Note that `types` only returns classes. You can use
+  // `mixins` to visit mixins, `enums` to visit enum, `functionTypeAliases`
+  // to visit typedefs, etc.
+  for (ClassElement classElement in unit.types) {
+    if (classElement.isPublic) {
+      // Hack: Filter out some difficult types.
+      // TODO (felih): include filtered types.
+      if (classElement.name.startsWith('Unmodifiable')) continue;
+      if (classElement.name.startsWith('Iterable')) continue;
+      if (classElement.name.startsWith('BigInt')) continue;
+      if (classElement.name.startsWith('DateTime')) continue;
+      if (classElement.name.startsWith('Uri')) continue;
+      // Compute heuristic to decide whether to include the type.
+      int no = countOperators(classElement);
+      if (no > operatorCountThreshold) {
+        allTypes.add(classElement.type);
+      }
+    }
+  }
+}
+
+// Get all interface implemented by type.
+Set<String> getInterfaces(InterfaceType tp) {
+  Set<String> iTypes = new Set<String>();
+  for (InterfaceType iTyp in tp.interfaces) {
+    String ifTypName = getConstName(iTyp.displayName);
+    iTypes.add(ifTypName);
+    iTypes = iTypes.union(getInterfaces(iTyp));
+  }
+  return iTypes;
+}
+
+// Get interface and inheritance relationships for all types.
+void getInterfaceRels(Set<InterfaceType> allTypes) {
+  for (InterfaceType tp in allTypes) {
+    String typName = getConstName(tp.displayName);
+    for (String ifTypName in getInterfaces(tp)) {
+      interfaceRels[ifTypName] ??= new Set<String>();
+      interfaceRels[ifTypName].add(typName);
+      if (ifTypName.contains('ITERABLE')) {
+        iterableTypes1.add(typName);
+      }
+    }
+    for (InterfaceType it in tp.element.allSupertypes) {
+      String ifTypName = getConstName(it.displayName);
+      interfaceRels[ifTypName] ??= new Set<String>();
+      interfaceRels[ifTypName].add(typName);
+    }
+  }
+  // If interface can be instantiated,
+  // add it to the relation list so that we can
+  // do tp1 = oneof(interfaceRels[tp2]) in dartfuzz with a chance of
+  // tp1 == tp1.
+  for (InterfaceType tp in allTypes) {
+    String typName = getConstName(tp.displayName);
+    if (interfaceRels.containsKey(typName)) {
+      interfaceRels[typName].add(typName);
+    }
+  }
+}
+
+main(List<String> arguments) async {
+  final parser = new ArgParser()
+    ..addOption('dart-top', help: 'explicit value for \$DART_TOP')
+    ..addOption('depth',
+        help: 'Nesting depth, e.g. List<String> is depth 0, ' +
+            'List<List<String>>' +
+            'is depth 1. Remark: dart type tables grow ' +
+            'exponentially with this, ' +
+            'therefore types with higher nesting ' +
+            'depth are partially filtered.',
+        defaultsTo: '1');
+  try {
+    final results = parser.parse(arguments);
+    int depth = int.parse(results['depth']);
+    Set<InterfaceType> allTypes = new Set<InterfaceType>();
+    // Filter types to instantiate parameterized types with, this excludes
+    // complex types like Int8List (might be added later).
+    Set<String> iTypeFilter = {'int', 'bool', 'double', 'String'};
+    // Extract basic types from dart::core and dart::typed_data.
+    await getDataTypes(allTypes, results['dart-top']);
+    // Instantiate parameterized types like List<E>.
+    allTypes = instantiateAllTypes(allTypes, iTypeFilter, depth, maxNew: 64);
+    // Extract interface Relations between types.
+    getInterfaceRels(allTypes);
+    // Extract operators from instantiated types.
+    getOperators(allTypes);
+    // Analyze instantiated types to get elementof/subscript and floating point
+    // information.
+    analyzeTypes(allTypes);
+    // Print everything.
+    printTypeTable(allTypes);
+    printTypeTable(allTypes, fp: false);
+    printTypeTable(allTypes, flatTp: true);
+    printTypeTable(allTypes, fp: false, flatTp: true);
+  } catch (e) {
+    print('Usage: dart gen_type_table.dart [OPTIONS]\n${parser.usage}\n$e');
+    exitCode = 255;
+  }
+}
diff --git a/runtime/tools/dartfuzz/gen_util.dart b/runtime/tools/dartfuzz/gen_util.dart
new file mode 100644
index 0000000..3ab635c
--- /dev/null
+++ b/runtime/tools/dartfuzz/gen_util.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+
+/// Wrapper class for some static utilities.
+class GenUtil {
+  // Picks a top directory (command line, environment, or current).
+  static String getTop(String top) {
+    if (top == null || top == '') {
+      top = Platform.environment['DART_TOP'];
+    }
+    if (top == null || top == '') {
+      top = Directory.current.path;
+    }
+    return top;
+  }
+
+  // Create an analyzer session.
+  static AnalysisSession createAnalysisSession([String dart_top]) {
+    // Set paths. Note that for this particular use case, packageRoot can be
+    // any directory. Here, we set it to the top of the SDK development, and
+    // derive the required sdkPath from there.
+    final String packageRoot = getTop(dart_top);
+    if (packageRoot == null) {
+      throw StateError('No environment variable DART_TOP');
+    }
+    final sdkPath = '$packageRoot/tools/sdks/dart-sdk';
+
+    // This does most of the hard work of getting the analyzer configured
+    // correctly. Typically the included paths are the files and directories
+    // that need to be analyzed, but the SDK is always available, so it isn't
+    // really important for this particular use case. We use the implementation
+    // class in order to pass in the sdkPath directly.
+    final provider = PhysicalResourceProvider.INSTANCE;
+    final collection = AnalysisContextCollectionImpl(
+        includedPaths: <String>[packageRoot],
+        excludedPaths: <String>[packageRoot + "/pkg/front_end/test"],
+        resourceProvider: provider,
+        sdkPath: sdkPath);
+    return collection.contexts[0].currentSession;
+  }
+}
diff --git a/runtime/tools/embedder_layering_check.py b/runtime/tools/embedder_layering_check.py
new file mode 100644
index 0000000..d49b705
--- /dev/null
+++ b/runtime/tools/embedder_layering_check.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Simple tool for verifying that sources from the standalone embedder do not
+# directly include sources from the VM or vice versa.
+
+import glob
+import os
+import re
+import sys
+
+INCLUDE_DIRECTIVE_RE = re.compile(r'^#include "(.*)"')
+
+PLATFORM_LAYER_RE = re.compile(r'^runtime/platform/')
+VM_LAYER_RE = re.compile(r'^runtime/(vm|lib)/')
+BIN_LAYER_RE = re.compile(r'^runtime/bin/')
+
+# Tests that don't match the simple case of *_test.cc.
+EXTRA_TEST_FILES = [
+    'runtime/bin/run_vm_tests.cc', 'runtime/vm/libfuzzer/dart_libfuzzer.cc'
+]
+
+
+def CheckFile(sdk_root, path):
+    includes = set()
+    with open(os.path.join(sdk_root, path)) as file:
+        for line in file:
+            m = INCLUDE_DIRECTIVE_RE.match(line)
+            if m is not None:
+                header = os.path.join('runtime', m.group(1))
+                if os.path.isfile(os.path.join(sdk_root, header)):
+                    includes.add(header)
+
+    errors = []
+    for include in includes:
+        if PLATFORM_LAYER_RE.match(path):
+            if VM_LAYER_RE.match(include):
+                errors.append(
+                    'LAYERING ERROR: %s must not include %s' % (path, include))
+            elif BIN_LAYER_RE.match(include):
+                errors.append(
+                    'LAYERING ERROR: %s must not include %s' % (path, include))
+        elif VM_LAYER_RE.match(path):
+            if BIN_LAYER_RE.match(include):
+                errors.append(
+                    'LAYERING ERROR: %s must not include %s' % (path, include))
+        elif BIN_LAYER_RE.match(path):
+            if VM_LAYER_RE.match(include):
+                errors.append(
+                    'LAYERING ERROR: %s must not include %s' % (path, include))
+    return errors
+
+
+def CheckDir(sdk_root, dir):
+    errors = []
+    for file in os.listdir(dir):
+        path = os.path.join(dir, file)
+        if os.path.isdir(path):
+            errors += CheckDir(sdk_root, path)
+        elif path.endswith('test.cc') or path in EXTRA_TEST_FILES:
+            None  # Tests may violate layering.
+        elif path.endswith('.cc') or path.endswith('.h'):
+            errors += CheckFile(sdk_root, os.path.relpath(path, sdk_root))
+    return errors
+
+
+def DoCheck(sdk_root):
+    return CheckDir(sdk_root, 'runtime')
+
+
+if __name__ == '__main__':
+    errors = DoCheck('.')
+    print '\n'.join(errors)
+    if errors:
+        sys.exit(-1)
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 9223327..d5867a4 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -68,7 +68,10 @@
   extra_deps = [ "//third_party/icu" ]
   if (is_fuchsia) {
     if (using_fuchsia_sdk) {
-      extra_deps += [ "$fuchsia_sdk_root/pkg:sys_cpp" ]
+      extra_deps += [
+        "$fuchsia_sdk_root/fidl:fuchsia.deprecatedtimezone",
+        "$fuchsia_sdk_root/pkg:sys_cpp",
+      ]
     } else {
       extra_deps += [
         # TODO(US-399): Remove time_service specific code when it is no longer
diff --git a/runtime/vm/bitmap_test.cc b/runtime/vm/bitmap_test.cc
index b48a204..a9a1add 100644
--- a/runtime/vm/bitmap_test.cc
+++ b/runtime/vm/bitmap_test.cc
@@ -37,7 +37,7 @@
     value = !value;
   }
   // Create a StackMap object from the builder and verify its contents.
-  const StackMap& stackmap1 = StackMap::Handle(StackMap::New(0, builder1, 0));
+  const StackMap& stackmap1 = StackMap::Handle(StackMap::New(builder1, 0));
   EXPECT_EQ(1024, stackmap1.Length());
   OS::PrintErr("%s\n", stackmap1.ToCString());
   value = true;
@@ -62,7 +62,7 @@
   for (int32_t i = 1025; i <= 2048; i++) {
     EXPECT(!builder1->Get(i));
   }
-  const StackMap& stackmap2 = StackMap::Handle(StackMap::New(0, builder1, 0));
+  const StackMap& stackmap2 = StackMap::Handle(StackMap::New(builder1, 0));
   EXPECT_EQ(2049, stackmap2.Length());
   for (int32_t i = 0; i <= 256; i++) {
     EXPECT(!stackmap2.IsObject(i));
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index f3ae235..37dcfdf 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -400,6 +400,8 @@
   V(Wasm_initMemory, 3)                                                        \
   V(Wasm_growMemory, 2)                                                        \
   V(Wasm_initInstance, 3)                                                      \
+  V(Wasm_initMemoryFromInstance, 2)                                            \
+  V(Wasm_getMemoryPages, 1)                                                    \
   V(Wasm_initFunction, 4)                                                      \
   V(Wasm_callFunction, 2)
 
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index 0d4bd00..fd5fd33 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -49,21 +49,22 @@
 void StackMapTableBuilder::AddEntry(intptr_t pc_offset,
                                     BitmapBuilder* bitmap,
                                     intptr_t register_bit_count) {
-  stack_map_ = StackMap::New(pc_offset, bitmap, register_bit_count);
+  ASSERT(Smi::IsValid(pc_offset));
+  pc_offset_ = Smi::New(pc_offset);
+  stack_map_ = StackMap::New(bitmap, register_bit_count);
+  list_.Add(pc_offset_, Heap::kOld);
   list_.Add(stack_map_, Heap::kOld);
 }
 
 bool StackMapTableBuilder::Verify() {
   intptr_t num_entries = Length();
-  StackMap& map1 = StackMap::Handle();
-  StackMap& map2 = StackMap::Handle();
   for (intptr_t i = 1; i < num_entries; i++) {
-    map1 = MapAt(i - 1);
-    map2 = MapAt(i);
+    pc_offset_ = OffsetAt(i - 1);
+    auto const offset1 = pc_offset_.Value();
+    pc_offset_ = OffsetAt(i);
+    auto const offset2 = pc_offset_.Value();
     // Ensure there are no duplicates and the entries are sorted.
-    if (map1.PcOffset() >= map2.PcOffset()) {
-      return false;
-    }
+    if (offset1 >= offset2) return false;
   }
   return true;
 }
@@ -77,10 +78,14 @@
   return Array::MakeFixedLength(list_);
 }
 
+RawSmi* StackMapTableBuilder::OffsetAt(intptr_t index) const {
+  pc_offset_ ^= list_.At(2 * index);
+  return pc_offset_.raw();
+}
+
 RawStackMap* StackMapTableBuilder::MapAt(intptr_t index) const {
-  StackMap& map = StackMap::Handle();
-  map ^= list_.At(index);
-  return map.raw();
+  stack_map_ ^= list_.At(2 * index + 1);
+  return stack_map_.raw();
 }
 
 RawExceptionHandlers* ExceptionHandlerList::FinalizeExceptionHandlers(
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index 5e2a52f..e77a651 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -47,7 +47,8 @@
 class StackMapTableBuilder : public ZoneAllocated {
  public:
   StackMapTableBuilder()
-      : stack_map_(StackMap::ZoneHandle()),
+      : pc_offset_(Smi::ZoneHandle()),
+        stack_map_(StackMap::ZoneHandle()),
         list_(GrowableObjectArray::ZoneHandle(
             GrowableObjectArray::New(Heap::kOld))) {}
   ~StackMapTableBuilder() {}
@@ -61,9 +62,11 @@
   RawArray* FinalizeStackMaps(const Code& code);
 
  private:
-  intptr_t Length() const { return list_.Length(); }
+  intptr_t Length() const { return list_.Length() / 2; }
+  RawSmi* OffsetAt(intptr_t index) const;
   RawStackMap* MapAt(intptr_t index) const;
 
+  Smi& pc_offset_;
   StackMap& stack_map_;
   GrowableObjectArray& list_;
   DISALLOW_COPY_AND_ASSIGN(StackMapTableBuilder);
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 6be5427..fb472d3 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -200,26 +200,6 @@
     StackZone stack_zone(T);
     zone_ = stack_zone.GetZone();
 
-    // Check that both the file open and write callbacks are available, though
-    // we only use the latter during IL processing.
-    if (FLAG_serialize_flow_graphs_to != nullptr &&
-        Dart::file_write_callback() != nullptr) {
-      if (auto file_open = Dart::file_open_callback()) {
-        auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
-        set_il_serialization_stream(file);
-      }
-      if (FLAG_populate_llvm_constant_pool) {
-        auto const object_store = I->object_store();
-        auto& llvm_constants = GrowableObjectArray::Handle(
-            zone_, GrowableObjectArray::New(16, Heap::kOld));
-        auto& llvm_constants_hash_table = Array::Handle(
-            zone_, HashTables::New<FlowGraphSerializer::LLVMConstantsMap>(
-                       16, Heap::kOld));
-        object_store->set_llvm_constant_pool(llvm_constants);
-        object_store->set_llvm_constant_hash_table(llvm_constants_hash_table);
-      }
-    }
-
     if (FLAG_use_bare_instructions) {
       // Since we keep the object pool until the end of AOT compilation, it
       // will hang on to its entries until the very end. Therefore we have
@@ -255,6 +235,32 @@
       ClassFinalizer::ClearAllCode(
           /*including_nonchanging_cids=*/FLAG_use_bare_instructions);
 
+      // After this point, it should be safe to serialize flow graphs produced
+      // during compilation and add constants to the LLVM constant pool.
+      //
+      // Check that both the file open and write callbacks are available, though
+      // we only use the latter during IL processing.
+      if (FLAG_serialize_flow_graphs_to != nullptr &&
+          Dart::file_write_callback() != nullptr) {
+        if (auto file_open = Dart::file_open_callback()) {
+          auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
+          set_il_serialization_stream(file);
+        }
+        if (FLAG_populate_llvm_constant_pool) {
+          auto const object_store = I->object_store();
+          auto& llvm_constants = GrowableObjectArray::Handle(
+              Z, GrowableObjectArray::New(16, Heap::kOld));
+          auto& llvm_functions = GrowableObjectArray::Handle(
+              Z, GrowableObjectArray::New(16, Heap::kOld));
+          auto& llvm_constant_hash_table = Array::Handle(
+              Z, HashTables::New<FlowGraphSerializer::LLVMPoolMap>(16,
+                                                                   Heap::kOld));
+          object_store->set_llvm_constant_pool(llvm_constants);
+          object_store->set_llvm_function_pool(llvm_functions);
+          object_store->set_llvm_constant_hash_table(llvm_constant_hash_table);
+        }
+      }
+
       // All stubs have already been generated, all of them share the same pool.
       // We use that pool to initialize our global object pool, to guarantee
       // stubs as well as code compiled from here on will have the same pool.
@@ -346,11 +352,11 @@
           Dart::file_write_callback() != nullptr) {
         if (auto file_close = Dart::file_close_callback()) {
           file_close(il_serialization_stream());
-          set_il_serialization_stream(nullptr);
         }
+        set_il_serialization_stream(nullptr);
         if (FLAG_populate_llvm_constant_pool) {
-          // We don't want the Array backing for the map from constants to
-          // indices in the snapshot, only the constant pool itself.
+          // We don't want the Array backing for any mappings in the snapshot,
+          // only the pools themselves.
           I->object_store()->set_llvm_constant_hash_table(Array::null_array());
         }
       }
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index ae216fa..b83a772 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1936,19 +1936,22 @@
   __ Ret();
 }
 
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized.
-// 'length-reg' (R2) contains tagged length.
+// Allocates a _OneByteString. The content is not initialized.
+// 'length-reg' (R2) contains the desired length as a _Smi or _Mint.
 // Returns new string as tagged pointer in R0.
-static void TryAllocateOnebyteString(Assembler* assembler,
+static void TryAllocateOneByteString(Assembler* assembler,
                                      Label* ok,
                                      Label* failure) {
   const Register length_reg = R2;
-  Label fail;
+  // _Mint length: call to runtime to produce error.
+  __ BranchIfNotSmi(length_reg, failure);
+  // Negative length: call to runtime to produce error.
+  __ cmp(length_reg, Operand(0));
+  __ b(failure, LT);
+
   NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R0, kOneByteStringCid));
   NOT_IN_PRODUCT(__ MaybeTraceAllocation(R0, failure));
   __ mov(R8, Operand(length_reg));  // Save the length register.
-  // TODO(koda): Protect against negative length and overflow here.
   __ SmiUntag(length_reg);
   const intptr_t fixed_size_plus_alignment_padding =
       target::String::InstanceSize() +
@@ -1962,7 +1965,7 @@
 
   // length_reg: allocation size.
   __ adds(R1, R0, Operand(length_reg));
-  __ b(&fail, CS);  // Fail on unsigned overflow.
+  __ b(failure, CS);  // Fail on unsigned overflow.
 
   // Check if the allocation fits into the remaining space.
   // R0: potential new object start.
@@ -1970,7 +1973,7 @@
   // R2: allocation size.
   __ ldr(NOTFP, Address(THR, target::Thread::end_offset()));
   __ cmp(R1, Operand(NOTFP));
-  __ b(&fail, CS);
+  __ b(failure, CS);
 
   // Successfully allocated the object(s), now update top to point to
   // next object start and initialize the object.
@@ -2010,9 +2013,6 @@
 
   NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2));
   __ b(ok);
-
-  __ Bind(&fail);
-  __ b(failure);
 }
 
 // Arg0: OneByteString (receiver).
@@ -2033,7 +2033,7 @@
   __ b(normal_ir_body, NE);  // 'start', 'end' not Smi.
 
   __ sub(R2, R2, Operand(TMP));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body);
   __ Bind(&ok);
   // R0: new string as tagged pointer.
   // Copy string.
@@ -2092,7 +2092,7 @@
                                              Label* normal_ir_body) {
   __ ldr(R2, Address(SP, 0 * target::kWordSize));  // Length.
   Label ok;
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body);
 
   __ Bind(&ok);
   __ Ret();
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index d96d9fc..2ae8fb3 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1999,15 +1999,18 @@
   __ ret();
 }
 
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized.
-// 'length-reg' (R2) contains tagged length.
+// Allocates a _OneByteString. The content is not initialized.
+// 'length-reg' (R2) contains the desired length as a _Smi or _Mint.
 // Returns new string as tagged pointer in R0.
-static void TryAllocateOnebyteString(Assembler* assembler,
+static void TryAllocateOneByteString(Assembler* assembler,
                                      Label* ok,
                                      Label* failure) {
   const Register length_reg = R2;
-  Label fail;
+  // _Mint length: call to runtime to produce error.
+  __ BranchIfNotSmi(length_reg, failure);
+  // negative length: call to runtime to produce error.
+  __ tbnz(failure, length_reg, compiler::target::kBitsPerWord - 1);
+
   NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, R0, failure));
   __ mov(R6, length_reg);  // Save the length register.
   // TODO(koda): Protect against negative length and overflow here.
@@ -2030,7 +2033,7 @@
 
   // length_reg: allocation size.
   __ adds(R1, R0, Operand(length_reg));
-  __ b(&fail, CS);  // Fail on unsigned overflow.
+  __ b(failure, CS);  // Fail on unsigned overflow.
 
   // Check if the allocation fits into the remaining space.
   // R0: potential new object start.
@@ -2038,7 +2041,7 @@
   // R2: allocation size.
   __ ldr(R7, Address(THR, target::Thread::end_offset()));
   __ cmp(R1, Operand(R7));
-  __ b(&fail, CS);
+  __ b(failure, CS);
 
   // Successfully allocated the object(s), now update top to point to
   // next object start and initialize the object.
@@ -2072,9 +2075,6 @@
   __ StoreIntoObjectNoBarrier(
       R0, FieldAddress(R0, target::String::length_offset()), R6);
   __ b(ok);
-
-  __ Bind(&fail);
-  __ b(failure);
 }
 
 // Arg0: OneByteString (receiver).
@@ -2094,7 +2094,7 @@
   __ BranchIfNotSmi(R3, normal_ir_body);  // 'start', 'end' not Smi.
 
   __ sub(R2, R2, Operand(TMP));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body);
   __ Bind(&ok);
   // R0: new string as tagged pointer.
   // Copy string.
@@ -2155,7 +2155,7 @@
   Label ok;
 
   __ ldr(R2, Address(SP, 0 * target::kWordSize));  // Length.
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body);
 
   __ Bind(&ok);
   __ ret();
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 690df69..d53462a 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1951,13 +1951,19 @@
   __ ret();
 }
 
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized. 'length-reg' contains tagged length.
+// Allocates a _OneByteString. The content is not initialized.
+// 'length-reg' contains the desired length as a _Smi or _Mint.
 // Returns new string as tagged pointer in EAX.
-static void TryAllocateOnebyteString(Assembler* assembler,
+static void TryAllocateOneByteString(Assembler* assembler,
                                      Label* ok,
                                      Label* failure,
                                      Register length_reg) {
+  // _Mint length: call to runtime to produce error.
+  __ BranchIfNotSmi(length_reg, failure);
+  // negative length: call to runtime to produce error.
+  __ cmpl(length_reg, Immediate(0));
+  __ j(LESS, failure);
+
   NOT_IN_PRODUCT(
       __ MaybeTraceAllocation(kOneByteStringCid, EAX, failure, false));
   if (length_reg != EDI) {
@@ -2048,7 +2054,7 @@
   __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
 
   __ subl(EDI, Address(ESP, +kStartIndexOffset));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body, EDI);
   __ Bind(&ok);
   // EAX: new string as tagged pointer.
   // Copy string.
@@ -2098,7 +2104,7 @@
                                              Label* normal_ir_body) {
   __ movl(EDI, Address(ESP, +1 * target::kWordSize));  // Length.
   Label ok;
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body, EDI);
   // EDI: Start address to copy from (untagged).
 
   __ Bind(&ok);
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index d210d67..02ec2c2 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1977,13 +1977,19 @@
   __ ret();
 }
 
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized. 'length-reg' contains tagged length.
+// Allocates a _OneByteString. The content is not initialized.
+// 'length-reg' contains the desired length as a _Smi or _Mint.
 // Returns new string as tagged pointer in RAX.
-static void TryAllocateOnebyteString(Assembler* assembler,
+static void TryAllocateOneByteString(Assembler* assembler,
                                      Label* ok,
                                      Label* failure,
                                      Register length_reg) {
+  // _Mint length: call to runtime to produce error.
+  __ BranchIfNotSmi(length_reg, failure);
+  // negative length: call to runtime to produce error.
+  __ cmpq(length_reg, Immediate(0));
+  __ j(LESS, failure);
+
   NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, failure, false));
   if (length_reg != RDI) {
     __ movq(RDI, length_reg);
@@ -2076,7 +2082,7 @@
   __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
 
   __ subq(RDI, Address(RSP, +kStartIndexOffset));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body, RDI);
   __ Bind(&ok);
   // RAX: new string as tagged pointer.
   // Copy string.
@@ -2126,7 +2132,7 @@
                                              Label* normal_ir_body) {
   __ movq(RDI, Address(RSP, +1 * target::kWordSize));  // Length.v=
   Label ok;
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
+  TryAllocateOneByteString(assembler, &ok, normal_ir_body, RDI);
   // RDI: Start address to copy from (untagged).
 
   __ Bind(&ok);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 0902183..8ce6936 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -302,6 +302,19 @@
   Emit(encoding);
 }
 
+void Assembler::rbit(Register rd, Register rm, Condition cond) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(rm != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  ASSERT(rd != PC);
+  ASSERT(rm != PC);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B26 |
+                     B25 | B23 | B22 | B21 | B20 | (0xf << 16) |
+                     ArmEncode::Rd(rd) | (0xf << 8) | B5 | B4 |
+                     static_cast<int32_t>(rm);
+  Emit(encoding);
+}
+
 void Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
   ASSERT(cond != kNoCondition);
   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | B25 | B24 |
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 904890d..1180d8b 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -445,6 +445,7 @@
 
   // Miscellaneous data-processing instructions.
   void clz(Register rd, Register rm, Condition cond = AL);
+  void rbit(Register rd, Register rm, Condition cond = AL);
 
   // Multiply instructions.
   void mul(Register rd, Register rn, Register rm, Condition cond = AL);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 972b1dc..6053347 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -777,6 +777,11 @@
     EmitMiscDP1Source(CLZ, rd, rn, kDoubleWord);
   }
 
+  // Reverse bits.
+  void rbit(Register rd, Register rn) {
+    EmitMiscDP1Source(RBIT, rd, rn, kDoubleWord);
+  }
+
   // Misc. arithmetic.
   void udiv(Register rd, Register rn, Register rm) {
     EmitMiscDP2Source(UDIV, rd, rn, rm, kDoubleWord);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index 2817361..fc38188 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -796,6 +796,19 @@
   EXPECT_EQ(0, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
 }
 
+ASSEMBLER_TEST_GENERATE(Rbit, assembler) {
+  const int64_t immediate = 0x0000000000000015;
+  __ LoadImmediate(R0, immediate);
+  __ rbit(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Rbit, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  const int64_t expected = 0xa800000000000000;
+  EXPECT_EQ(expected, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
 // Comparisons, branching.
 ASSEMBLER_TEST_GENERATE(BranchALForward, assembler) {
   Label l;
diff --git a/runtime/vm/compiler/assembler/assembler_arm_test.cc b/runtime/vm/compiler/assembler/assembler_arm_test.cc
index 4e69f74..ca70de7 100644
--- a/runtime/vm/compiler/assembler/assembler_arm_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm_test.cc
@@ -986,6 +986,19 @@
   EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Clz, test->entry()));
 }
 
+ASSEMBLER_TEST_GENERATE(Rbit, assembler) {
+  __ mov(R0, Operand(0x15));
+  __ rbit(R0, R0);
+  __ bx(LR);
+}
+
+ASSEMBLER_TEST_RUN(Rbit, test) {
+  EXPECT(test != NULL);
+  typedef int (*Rbit)() DART_UNUSED;
+  const int32_t expected = 0xa8000000;
+  EXPECT_EQ(expected, EXECUTE_TEST_CODE_INT32(Rbit, test->entry()));
+}
+
 ASSEMBLER_TEST_GENERATE(Tst, assembler) {
   Label skip;
 
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index b7aa53d..64cd1af 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -281,10 +281,12 @@
   THR_Print("StackMaps for function '%s' {\n", function_fullname);
   if (code.stackmaps() != Array::null()) {
     const Array& stackmap_table = Array::Handle(zone, code.stackmaps());
+    auto& offset = Smi::Handle(zone);
     StackMap& map = StackMap::Handle(zone);
-    for (intptr_t i = 0; i < stackmap_table.Length(); ++i) {
-      map ^= stackmap_table.At(i);
-      THR_Print("%s\n", map.ToCString());
+    for (intptr_t i = 0; i < stackmap_table.Length(); i += 2) {
+      offset ^= stackmap_table.At(i);
+      map ^= stackmap_table.At(i + 1);
+      THR_Print("0x%08" Px ": %s\n", offset.Value(), map.ToCString());
     }
   }
   THR_Print("}\n");
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 1cf9e00..8552753 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -259,6 +259,8 @@
     case KernelBytecode::kInstantiateType_Wide:
     case KernelBytecode::kDirectCall:
     case KernelBytecode::kDirectCall_Wide:
+    case KernelBytecode::kUncheckedDirectCall:
+    case KernelBytecode::kUncheckedDirectCall_Wide:
     case KernelBytecode::kInterfaceCall:
     case KernelBytecode::kInterfaceCall_Wide:
     case KernelBytecode::kInstantiatedInterfaceCall:
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index afef14c..39e8dc5 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1256,6 +1256,12 @@
       Definition* reaching_defn = env->RemoveLast();
       Definition* input_defn = v->definition();
       if (input_defn != reaching_defn) {
+        // Under OSR, constants can reside on the expression stack. Just
+        // generate the constant rather than going through a synthetic phi.
+        if (input_defn->IsConstant() && reaching_defn->IsPhi()) {
+          ASSERT(IsCompiledForOsr() && env->length() < osr_variable_count());
+          reaching_defn = GetConstant(input_defn->AsConstant()->value());
+        }
         // Note: constants can only be replaced with other constants.
         ASSERT(input_defn->IsLoadLocal() || input_defn->IsStoreLocal() ||
                input_defn->IsDropTemps() || input_defn->IsMakeTemp() ||
@@ -1286,7 +1292,6 @@
         // with the incoming parameter that mimics the stack slot.
         ASSERT(IsCompiledForOsr());
         PushArgumentInstr* push_arg = current->PushArgumentAt(i);
-        ASSERT(push_arg->IsPushArgument());
         ASSERT(reaching_defn->ssa_temp_index() != -1);
         ASSERT(reaching_defn->IsPhi() || reaching_defn == constant_dead());
         push_arg->ReplaceUsesWith(push_arg->InputAt(0)->definition());
@@ -1297,6 +1302,18 @@
         push_arg->value()->set_definition(reaching_defn);
         InsertBefore(insert_at, push_arg, nullptr, FlowGraph::kEffect);
         insert_at = push_arg;
+        // Since reaching_defn was not the expected PushArgument, we must
+        // change all its environment uses from the insertion point onward
+        // to the newly created PushArgument. This ensures that the stack
+        // depth computations (based on environment presence of PushArguments)
+        // is done correctly.
+        for (Value::Iterator it(reaching_defn->env_use_list()); !it.Done();
+             it.Advance()) {
+          Instruction* instruction = it.Current()->instruction();
+          if (instruction->IsDominatedBy(push_arg)) {
+            instruction->ReplaceInEnvironment(reaching_defn, push_arg);
+          }
+        }
       }
     }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 54a3630..0bbb995 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -394,14 +394,14 @@
   ASSERT(def->value()->definition() != def);
 }
 
-void FlowGraphChecker::VisitInstanceCall(InstanceCallInstr* instr) {
+void FlowGraphChecker::VisitInstanceCall(InstanceCallInstr* call) {
   // Force-optimized functions may not have instance calls inside them because
   // we do not reset ICData for these.
   ASSERT(!flow_graph_->function().ForceOptimize());
 }
 
 void FlowGraphChecker::VisitPolymorphicInstanceCall(
-    PolymorphicInstanceCallInstr* instr) {
+    PolymorphicInstanceCallInstr* call) {
   // Force-optimized functions may not have instance calls inside them because
   // we do not reset ICData for these.
   ASSERT(!flow_graph_->function().ForceOptimize());
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 6ed9d5b..16371b3 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1100,6 +1100,12 @@
 
   __ PopNativeCalleeSavedRegisters();
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Leave the entry frame.
   __ LeaveFrame(1 << LR | 1 << FP);
 
@@ -1157,6 +1163,12 @@
   // Save a space for the code object.
   __ PushImmediate(0);
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   __ PushNativeCalleeSavedRegisters();
 
   // Load the thread object. If we were called by a trampoline, the thread is
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 3f7f28f..2f8a4db 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -989,6 +989,12 @@
 
   __ PopNativeCalleeSavedRegisters();
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Leave the entry frame.
   __ LeaveFrame();
 
@@ -1044,6 +1050,12 @@
   // Save a space for the code object.
   __ PushImmediate(0);
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   __ PushNativeCalleeSavedRegisters();
 
   // Load the thread object. If we were called by a trampoline, the thread is
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index ff3df26..a05e810 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -197,6 +197,12 @@
   __ popl(ESI);
   __ popl(EBX);
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Leave the entry frame.
   __ LeaveFrame();
 
@@ -1030,6 +1036,12 @@
   __ xorl(EAX, EAX);
   __ pushl(EAX);
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save ABI callee-saved registers.
   __ pushl(EBX);
   __ pushl(ESI);
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index 486973b..71844b7 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -39,10 +39,13 @@
       zone_(zone),
       object_store_(flow_graph->thread()->isolate()->object_store()),
       open_recursive_types_(zone_),
-      llvm_pool_(
+      llvm_constants_(
           GrowableObjectArray::Handle(zone_,
                                       object_store_->llvm_constant_pool())),
-      llvm_map_(zone_, object_store_->llvm_constant_hash_table()),
+      llvm_functions_(
+          GrowableObjectArray::Handle(zone_,
+                                      object_store_->llvm_function_pool())),
+      llvm_constant_map_(zone_, object_store_->llvm_constant_hash_table()),
       llvm_index_(Smi::Handle(zone_)),
       tmp_string_(String::Handle(zone_)),
       array_type_args_((TypeArguments::Handle(zone_))),
@@ -70,7 +73,7 @@
 }
 
 FlowGraphSerializer::~FlowGraphSerializer() {
-  object_store_->set_llvm_constant_hash_table(llvm_map_.Release());
+  object_store_->set_llvm_constant_hash_table(llvm_constant_map_.Release());
 }
 
 void FlowGraphSerializer::SerializeToBuffer(const FlowGraph* flow_graph,
@@ -326,6 +329,11 @@
   for (intptr_t i = 1; i < block_order.length(); ++i) {
     sexp->Add(block_order[i]->ToSExpression(this));
   }
+  if (FLAG_populate_llvm_constant_pool) {
+    auto const new_index = llvm_functions_.Length();
+    llvm_functions_.Add(flow_graph_->function());
+    AddExtraInteger(sexp, "llvm_index", new_index);
+  }
   return sexp;
 }
 
@@ -745,13 +753,14 @@
         elem->AddExtra("type", type->ToSExpression(this));
       }
     }
-    if (FLAG_populate_llvm_constant_pool) {
-      auto const pool_len = llvm_pool_.Length();
+    // Only add constants to the LLVM constant pool that are actually used in
+    // the flow graph.
+    if (FLAG_populate_llvm_constant_pool && definition->HasUses()) {
+      auto const pool_len = llvm_constants_.Length();
       llvm_index_ = Smi::New(pool_len);
-      llvm_index_ =
-          Smi::RawCast(llvm_map_.InsertOrGetValue(value, llvm_index_));
+      llvm_index_ ^= llvm_constant_map_.InsertOrGetValue(value, llvm_index_);
       if (llvm_index_.Value() == pool_len) {
-        llvm_pool_.Add(value);
+        llvm_constants_.Add(value);
       }
       AddExtraInteger(elem, "llvm_index", llvm_index_.Value());
     }
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
index 7fb3088..3e6e6af 100644
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ b/runtime/vm/compiler/backend/il_serializer.h
@@ -131,9 +131,9 @@
   IntMap<const Type*> open_recursive_types_;
 
   // Used for --populate-llvm-constant-pool in ConstantPoolToSExp.
-  class LLVMConstantMapKeyEqualsTraits : public AllStatic {
+  class LLVMPoolMapKeyEqualsTraits : public AllStatic {
    public:
-    static const char* Name() { return "LLVMConstantMapKeyEqualsTraits"; }
+    static const char* Name() { return "LLVMPoolMapKeyEqualsTraits"; }
     static bool ReportStats() { return false; }
 
     static bool IsMatch(const Object& a, const Object& b) {
@@ -145,10 +145,11 @@
       return obj.GetClassId();
     }
   };
-  typedef UnorderedHashMap<LLVMConstantMapKeyEqualsTraits> LLVMConstantsMap;
+  typedef UnorderedHashMap<LLVMPoolMapKeyEqualsTraits> LLVMPoolMap;
 
-  GrowableObjectArray& llvm_pool_;
-  LLVMConstantsMap llvm_map_;
+  GrowableObjectArray& llvm_constants_;
+  GrowableObjectArray& llvm_functions_;
+  LLVMPoolMap llvm_constant_map_;
   Smi& llvm_index_;
 
   // Handles used across functions, where the contained value is used
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 10face2..0e3b73e 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -170,6 +170,12 @@
   __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
                   CallingConventions::kCalleeSaveXmmRegisters);
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Leave the entry frame.
   __ LeaveFrame();
 
@@ -1030,6 +1036,12 @@
   // NativeReturnInstr::EmitNativeCode.
   __ EnterFrame(0);
 
+#if defined(TARGET_OS_FUCHSIA)
+  UNREACHABLE(); // Fuchsia does not allow dart:ffi.
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the argument registers, in reverse order.
   for (intptr_t i = argument_locations_->length(); i-- > 0;) {
     SaveArgument(compiler, argument_locations_->At(i));
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 349db75..be09321 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -797,7 +797,7 @@
   LoadLocal(local_index);
 }
 
-void BytecodeFlowGraphBuilder::BuildDirectCall() {
+void BytecodeFlowGraphBuilder::BuildDirectCallCommon(bool is_unchecked_call) {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
@@ -857,7 +857,7 @@
       *ic_data_array_, B->GetNextDeoptId(),
       target.IsDynamicFunction() ? ICData::kSuper : ICData::kStatic);
 
-  if (target.MayHaveUncheckedEntryPoint(isolate())) {
+  if (is_unchecked_call) {
     call->set_entry_kind(Code::EntryKind::kUnchecked);
   }
 
@@ -867,6 +867,14 @@
   B->Push(call);
 }
 
+void BytecodeFlowGraphBuilder::BuildDirectCall() {
+  BuildDirectCallCommon(/* is_unchecked_call = */ false);
+}
+
+void BytecodeFlowGraphBuilder::BuildUncheckedDirectCall() {
+  BuildDirectCallCommon(/* is_unchecked_call = */ true);
+}
+
 static void ComputeTokenKindAndCheckedArguments(
     const String& name,
     const ArgumentsDescriptor& arg_desc,
@@ -1346,6 +1354,19 @@
   code_ <<= instr;
 }
 
+void BytecodeFlowGraphBuilder::BuildCheckReceiverForNull() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const String& selector = String::Cast(ConstantAt(DecodeOperandD()).value());
+
+  LocalVariable* receiver_temp = B->MakeTemporary();
+  code_ +=
+      B->CheckNull(position_, receiver_temp, selector, /*clear_temp=*/false);
+  code_ += B->Drop();
+}
+
 void BytecodeFlowGraphBuilder::BuildJump() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index 1e84f92..814b8df 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -167,6 +167,7 @@
                         int num_args);
   void BuildIntOp(const String& name, Token::Kind token_kind, int num_args);
   void BuildDoubleOp(const String& name, Token::Kind token_kind, int num_args);
+  void BuildDirectCallCommon(bool is_unchecked_call);
   void BuildInterfaceCallCommon(bool is_unchecked_call,
                                 bool is_instantiated_call);
 
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 6f2240a..0f3eb24 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -715,6 +715,7 @@
     kInterfaceCall,
     kInstantiatedInterfaceCall,
     kDynamicCall,
+    kDirectCallViaDynamicForwarder,
   };
 
   enum InvocationKind {
@@ -915,6 +916,23 @@
         ASSERT(i < obj_count);
         obj = Object::null();
       } break;
+      case ConstantPoolTag::kDirectCallViaDynamicForwarder: {
+        // DirectCallViaDynamicForwarder constant occupies 2 entries.
+        // The first entry is used for target function.
+        obj = ReadObject();
+        ASSERT(obj.IsFunction());
+        name = Function::Cast(obj).name();
+        name = Function::CreateDynamicInvocationForwarderName(name);
+        obj = Function::Cast(obj).GetDynamicInvocationForwarder(name);
+
+        pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
+                       ObjectPool::Patchability::kNotPatchable);
+        pool.SetObjectAt(i, obj);
+        ++i;
+        ASSERT(i < obj_count);
+        // The second entry is used for arguments descriptor.
+        obj = ReadObject();
+      } break;
       default:
         UNREACHABLE();
     }
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 0579418..8c36561 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -633,6 +633,7 @@
   static word active_exception_offset();
   static word active_stacktrace_offset();
   static word resume_pc_offset();
+  static word saved_shadow_call_stack_offset();
   static word marking_stack_block_offset();
   static word top_exit_frame_info_offset();
   static word top_resource_offset();
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index add5eab..0965a3c 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -212,7 +212,7 @@
     Thread_call_to_runtime_entry_point_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 132;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 648;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 652;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     228;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 156;
@@ -228,7 +228,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 180;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    632;
+    636;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 184;
 static constexpr dart::compiler::target::word
@@ -284,8 +284,10 @@
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 252;
 static constexpr dart::compiler::target::word Thread_resume_pc_offset = 628;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 632;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    636;
+    640;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 172;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
@@ -314,7 +316,7 @@
     Thread_write_barrier_entry_point_offset = 192;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     44;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 640;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 644;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -569,7 +571,7 @@
     Thread_call_to_runtime_entry_point_offset = 392;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1304;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1312;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     448;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 304;
@@ -585,7 +587,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 352;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1272;
+    1280;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 360;
 static constexpr dart::compiler::target::word
@@ -641,8 +643,10 @@
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 496;
 static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1264;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1272;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1280;
+    1288;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 336;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
@@ -672,7 +676,7 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     88;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1288;
+    1296;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -926,7 +930,7 @@
     Thread_call_to_runtime_entry_point_offset = 200;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 132;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 612;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 616;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     228;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 156;
@@ -942,7 +946,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 180;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    596;
+    600;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 184;
 static constexpr dart::compiler::target::word
@@ -998,8 +1002,10 @@
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 252;
 static constexpr dart::compiler::target::word Thread_resume_pc_offset = 592;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 596;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    600;
+    604;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 172;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
@@ -1028,7 +1034,7 @@
     Thread_write_barrier_entry_point_offset = 192;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     44;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 604;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 608;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -1279,7 +1285,7 @@
     Thread_call_to_runtime_entry_point_offset = 392;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 256;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1392;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1400;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     448;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 304;
@@ -1295,7 +1301,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 352;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1360;
+    1368;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 360;
 static constexpr dart::compiler::target::word
@@ -1351,8 +1357,10 @@
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 496;
 static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1352;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 1360;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1368;
+    1376;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 336;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
@@ -1382,7 +1390,7 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     88;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1376;
+    1384;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -1631,14 +1639,14 @@
     Thread_auto_scope_native_wrapper_entry_point_offset = 216;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 200;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 192;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 952;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 960;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
     256;
 static constexpr dart::compiler::target::word
     Thread_double_negate_address_offset = 248;
 static constexpr dart::compiler::target::word Thread_end_offset = 120;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    920;
+    928;
 static constexpr dart::compiler::target::word
     Thread_float_absolute_address_offset = 280;
 static constexpr dart::compiler::target::word
@@ -1658,8 +1666,10 @@
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 232;
 static constexpr dart::compiler::target::word Thread_resume_pc_offset = 912;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 920;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    928;
+    936;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 80;
@@ -1674,7 +1684,7 @@
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 160;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     88;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 936;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 944;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -1916,14 +1926,14 @@
     Thread_auto_scope_native_wrapper_entry_point_offset = 112;
 static constexpr dart::compiler::target::word Thread_bool_false_offset = 104;
 static constexpr dart::compiler::target::word Thread_bool_true_offset = 100;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 480;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 484;
 static constexpr dart::compiler::target::word Thread_double_abs_address_offset =
     132;
 static constexpr dart::compiler::target::word
     Thread_double_negate_address_offset = 128;
 static constexpr dart::compiler::target::word Thread_end_offset = 60;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    464;
+    468;
 static constexpr dart::compiler::target::word
     Thread_float_absolute_address_offset = 144;
 static constexpr dart::compiler::target::word
@@ -1943,8 +1953,10 @@
 static constexpr dart::compiler::target::word
     Thread_predefined_symbols_address_offset = 120;
 static constexpr dart::compiler::target::word Thread_resume_pc_offset = 460;
+static constexpr dart::compiler::target::word
+    Thread_saved_shadow_call_stack_offset = 464;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    468;
+    472;
 static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36;
 static constexpr dart::compiler::target::word
     Thread_stack_overflow_flags_offset = 40;
@@ -1959,7 +1971,7 @@
 static constexpr dart::compiler::target::word Thread_vm_tag_offset = 80;
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     44;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 472;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 476;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
 static constexpr dart::compiler::target::word Type_arguments_offset = 16;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index eb574eb..de860a7 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -198,6 +198,7 @@
   FIELD(Thread, object_null_offset)                                            \
   FIELD(Thread, predefined_symbols_address_offset)                             \
   FIELD(Thread, resume_pc_offset)                                              \
+  FIELD(Thread, saved_shadow_call_stack_offset)                                \
   FIELD(Thread, safepoint_state_offset)                                        \
   NOT_IN_DBC(FIELD(Thread, slow_type_test_stub_offset))                        \
   FIELD(Thread, stack_limit_offset)                                            \
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 3e8a5a4..b8d0cb9 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -1221,6 +1221,10 @@
     __ mov(THR, Operand(R3));
   }
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the current VMTag on the stack.
   __ LoadFromOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
   __ Push(R9);
@@ -1310,6 +1314,10 @@
   __ Pop(R4);
   __ StoreToOffset(kWord, R4, THR, target::Thread::vm_tag_offset());
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   __ PopNativeCalleeSavedRegisters();
 
   __ set_constant_pool_allowed(false);
@@ -1358,6 +1366,10 @@
     __ mov(THR, Operand(R3));
   }
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the current VMTag on the stack.
   __ LoadFromOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
   __ Push(R9);
@@ -1445,6 +1457,11 @@
   } else {
     __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize);
   }
+
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Restore CPU registers.
   __ PopList(kAbiPreservedCpuRegs);
   __ set_constant_pool_allowed(false);
@@ -3024,6 +3041,9 @@
   __ mov(THR, Operand(R3));  // Thread.
   __ mov(FP, Operand(R2));   // Frame_pointer.
   __ mov(SP, Operand(IP));   // Set Stack pointer.
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
   // Set the tag.
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 59674e3..326edcd 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -1323,12 +1323,19 @@
   __ ldr(TMP, Address(R3, target::Thread::invoke_dart_code_stub_offset()));
   __ Push(TMP);
 
+#if defined(TARGET_OS_FUCHSIA)
+  __ str(R18, Address(R3, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   __ PushNativeCalleeSavedRegisters();
 
   // Set up THR, which caches the current thread in Dart code.
   if (THR != R3) {
     __ mov(THR, R3);
   }
+
   // Refresh write barrier mask.
   __ ldr(BARRIER_MASK,
          Address(THR, target::Thread::write_barrier_mask_offset()));
@@ -1346,7 +1353,11 @@
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
+#if defined(TARGET_OS_FUCHSIA)
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23);
+#else
   ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -22);
+#endif
   __ Push(R6);
 
   // Mark that the thread is executing Dart code. Do this after initializing the
@@ -1417,7 +1428,18 @@
   __ Pop(R4);
   __ StoreToOffset(R4, THR, target::Thread::vm_tag_offset());
 
-  __ PopNativeCalleeSavedRegisters();
+
+#if defined(TARGET_OS_FUCHSIA)
+  __ mov (R3, THR);
+#endif
+
+  __ PopNativeCalleeSavedRegisters();  // Clobbers THR
+
+#if defined(TARGET_OS_FUCHSIA)
+  __ str(R18, Address(R3, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
 
   // Restore the frame pointer and C stack pointer and return.
   __ LeaveFrame();
@@ -1450,25 +1472,19 @@
                  target::Thread::invoke_dart_code_from_bytecode_stub_offset()));
   __ Push(TMP);
 
-  // Save the callee-saved registers.
-  for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
-    const Register r = static_cast<Register>(i);
-    // We use str instead of the Push macro because we will be pushing the PP
-    // register when it is not holding a pool-pointer since we are coming from
-    // C++ code.
-    __ str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
-  }
+#if defined(TARGET_OS_FUCHSIA)
+  __ str(R18, Address(R3, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
 
-  // Save the bottom 64-bits of callee-saved V registers.
-  for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
-    const VRegister r = static_cast<VRegister>(i);
-    __ PushDouble(r);
-  }
+  __ PushNativeCalleeSavedRegisters();
 
   // Set up THR, which caches the current thread in Dart code.
   if (THR != R3) {
     __ mov(THR, R3);
   }
+
   // Refresh write barrier mask.
   __ ldr(BARRIER_MASK,
          Address(THR, target::Thread::write_barrier_mask_offset()));
@@ -1486,7 +1502,11 @@
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
+#if defined(TARGET_OS_FUCHSIA)
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23);
+#else
   ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -22);
+#endif
   __ Push(R6);
 
   // Mark that the thread is executing Dart code. Do this after initializing the
@@ -1548,21 +1568,17 @@
   __ Pop(R4);
   __ StoreToOffset(R4, THR, target::Thread::vm_tag_offset());
 
-  // Restore the bottom 64-bits of callee-saved V registers.
-  for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
-    const VRegister r = static_cast<VRegister>(i);
-    __ PopDouble(r);
-  }
+#if defined(TARGET_OS_FUCHSIA)
+  __ mov (R3, THR);
+#endif
 
-  // Restore C++ ABI callee-saved registers.
-  for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
-    Register r = static_cast<Register>(i);
-    // We use ldr instead of the Pop macro because we will be popping the PP
-    // register when it is not holding a pool-pointer since we are returning to
-    // C++ code. We also skip the dart stack pointer SP, since we are still
-    // using it as the stack pointer.
-    __ ldr(r, Address(SP, 1 * target::kWordSize, Address::PostIndex));
-  }
+  __ PopNativeCalleeSavedRegisters();  // Clobbers THR
+
+#if defined(TARGET_OS_FUCHSIA)
+  __ str(R18, Address(R3, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
 
   // Restore the frame pointer and C stack pointer and return.
   __ LeaveFrame();
@@ -3127,6 +3143,11 @@
   __ mov(SP, R1);  // Stack pointer.
   __ mov(FP, R2);  // Frame_pointer.
   __ mov(THR, R3);
+#if defined(TARGET_OS_FUCHSIA)
+  __ ldr(R18, Address(THR, target::Thread::saved_shadow_call_stack_offset()));
+#elif defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
   __ ldr(BARRIER_MASK,
          Address(THR, target::Thread::write_barrier_mask_offset()));
   // Set the tag.
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 202ee75..06817a0 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -988,6 +988,10 @@
   // Set up THR, which caches the current thread in Dart code.
   __ movl(THR, EAX);
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the current VMTag on the stack.
   __ movl(ECX, Assembler::VMTagAddress());
   __ pushl(ECX);
@@ -1068,6 +1072,10 @@
   // Restore the current VMTag from the stack.
   __ popl(Assembler::VMTagAddress());
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Restore C++ ABI callee-saved registers.
   __ popl(EDI);
   __ popl(ESI);
@@ -1109,6 +1117,10 @@
   // Set up THR, which caches the current thread in Dart code.
   __ movl(THR, EAX);
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the current VMTag on the stack.
   __ movl(ECX, Assembler::VMTagAddress());
   __ pushl(ECX);
@@ -1181,6 +1193,10 @@
   // Restore the current VMTag from the stack.
   __ popl(Assembler::VMTagAddress());
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Restore C++ ABI callee-saved registers.
   __ popl(EDI);
   __ popl(ESI);
@@ -2520,6 +2536,9 @@
           Address(ESP, 1 * target::kWordSize));  // Load target PC into EBX.
   __ movl(ESP,
           Address(ESP, 2 * target::kWordSize));  // Load target stack_pointer.
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
   // Set tag.
   __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
   // Clear top exit frame.
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index b376b02..5bdc6d2 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -1244,6 +1244,10 @@
     __ movq(THR, kThreadReg);
   }
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the current VMTag on the stack.
   __ movq(RAX, Assembler::VMTagAddress());
   __ pushq(RAX);
@@ -1328,6 +1332,10 @@
   // Restore the current VMTag from the stack.
   __ popq(Assembler::VMTagAddress());
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Restore C++ ABI callee-saved registers.
   __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
                   CallingConventions::kCalleeSaveXmmRegisters);
@@ -1387,6 +1395,10 @@
     __ movq(THR, kThreadReg);
   }
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Save the current VMTag on the stack.
   __ movq(RAX, Assembler::VMTagAddress());
   __ pushq(RAX);
@@ -1477,6 +1489,10 @@
   // Restore the current VMTag from the stack.
   __ popq(Assembler::VMTagAddress());
 
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
+
   // Restore C++ ABI callee-saved registers.
   __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
                   CallingConventions::kCalleeSaveXmmRegisters);
@@ -3100,6 +3116,9 @@
   __ movq(THR, CallingConventions::kArg4Reg);
   __ movq(RBP, CallingConventions::kArg3Reg);
   __ movq(RSP, CallingConventions::kArg2Reg);
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
   // Set the tag.
   __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
   // Clear top exit frame.
@@ -3152,6 +3171,9 @@
 
   // Push the deopt pc.
   __ pushq(Address(THR, target::Thread::resume_pc_offset()));
+#if defined(USING_SHADOW_CALL_STACK)
+#error Unimplemented
+#endif
   GenerateDeoptimizationSequence(assembler, kEagerDeopt);
 
   // After we have deoptimized, jump to the correct frame.
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index a1f578c..b8fc2f1 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -753,6 +753,13 @@
             (Bits(22, 3) == 4));
   }
 
+  inline bool IsRbit() const {
+    ASSERT(ConditionField() != kSpecialCondition);
+    ASSERT(TypeField() == 3);
+    return ((Bits(4, 4) == 3) && (Bits(8, 4) == 15) && (Bits(16, 4) == 15) &&
+            (Bits(20, 8) == 111));
+  }
+
   // Test for VFP data processing or single transfer instructions of type 7.
   inline bool IsVFPDataProcessingOrSingleTransfer() const {
     ASSERT(ConditionField() != kSpecialCondition);
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index dca40c3..cca7779 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -32,7 +32,7 @@
   R15 = 15,  // SP in Dart code.
   R16 = 16,  // IP0 aka TMP
   R17 = 17,  // IP1 aka TMP2
-  R18 = 18,  // "platform register" on iOS.
+  R18 = 18,  // reserved on iOS, shadow call stack on Fuchsia.
   R19 = 19,
   R20 = 20,
   R21 = 21,
@@ -151,12 +151,21 @@
 const RegList kAbiArgumentCpuRegs = (1 << R0) | (1 << R1) | (1 << R2) |
                                     (1 << R3) | (1 << R4) | (1 << R5) |
                                     (1 << R6) | (1 << R7);
+#if defined(TARGET_OS_FUCHSIA)
+const RegList kAbiPreservedCpuRegs =
+    (1 << R18) | (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) |
+    (1 << R23) | (1 << R24) | (1 << R25) | (1 << R26) | (1 << R27) | (1 << R28);
+const Register kAbiFirstPreservedCpuReg = R18;
+const Register kAbiLastPreservedCpuReg = R28;
+const int kAbiPreservedCpuRegCount = 11;
+#else
 const RegList kAbiPreservedCpuRegs =
     (1 << R19) | (1 << R20) | (1 << R21) | (1 << R22) | (1 << R23) |
     (1 << R24) | (1 << R25) | (1 << R26) | (1 << R27) | (1 << R28);
 const Register kAbiFirstPreservedCpuReg = R19;
 const Register kAbiLastPreservedCpuReg = R28;
 const int kAbiPreservedCpuRegCount = 10;
+#endif
 const VRegister kAbiFirstPreservedFpuReg = V8;
 const VRegister kAbiLastPreservedFpuReg = V15;
 const int kAbiPreservedFpuRegCount = 8;
@@ -165,8 +174,7 @@
     (1 << SPREG) |  // Dart SP
     (1 << FPREG) | (1 << TMP) | (1 << TMP2) | (1 << PP) | (1 << THR) |
     (1 << LR) | (1 << BARRIER_MASK) | (1 << R31) |  // C++ SP
-    (1 << R18);                                     // iOS platform register.
-// TODO(rmacnak): Only reserve on Mac & iOS.
+    (1 << R18);
 constexpr intptr_t kNumberOfReservedCpuRegisters = 10;
 // CPU registers available to Dart allocator.
 const RegList kDartAvailableCpuRegs =
@@ -555,6 +563,7 @@
   MiscDP1SourceMask = 0x5fe00000,
   MiscDP1SourceFixed = DPRegisterFixed | B30 | B28 | B23 | B22,
   CLZ = MiscDP1SourceFixed | B12,
+  RBIT = MiscDP1SourceFixed,  // opc = '00'
 };
 
 // C3.5.8
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index f8d4489..a89756e 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -649,8 +649,8 @@
   V(JumpIfNotNull_Wide,                    T, WIDE, tgt, ___, ___)             \
   V(DirectCall,                          D_F, ORDN, num, num, ___)             \
   V(DirectCall_Wide,                     D_F, WIDE, num, num, ___)             \
-  V(Unused21,                              0, RESV, ___, ___, ___)             \
-  V(Unused22,                              0, RESV, ___, ___, ___)             \
+  V(UncheckedDirectCall,                 D_F, ORDN, num, num, ___)             \
+  V(UncheckedDirectCall_Wide,            D_F, WIDE, num, num, ___)             \
   V(InterfaceCall,                       D_F, ORDN, num, num, ___)             \
   V(InterfaceCall_Wide,                  D_F, WIDE, num, num, ___)             \
   V(Unused23,                              0, RESV, ___, ___, ___)             \
@@ -689,8 +689,8 @@
   V(MoveSpecial_Wide,                    A_Y, WIDE, num, xeg, ___)             \
   V(BooleanNegateTOS,                      0, ORDN, ___, ___, ___)             \
   V(EqualsNull,                            0, ORDN, ___, ___, ___)             \
-  V(Unused36,                              0, RESV, ___, ___, ___)             \
-  V(Unused37,                              0, RESV, ___, ___, ___)             \
+  V(CheckReceiverForNull,                  D, ORDN, lit, ___, ___)             \
+  V(CheckReceiverForNull_Wide,             D, WIDE, lit, ___, ___)             \
   V(NegateInt,                             0, ORDN, ___, ___, ___)             \
   V(AddInt,                                0, ORDN, ___, ___, ___)             \
   V(SubInt,                                0, ORDN, ___, ___, ___)             \
@@ -749,7 +749,7 @@
   // Maximum bytecode format version supported by VM.
   // The range of supported versions should include version produced by bytecode
   // generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
-  static const intptr_t kMaxSupportedBytecodeFormatVersion = 20;
+  static const intptr_t kMaxSupportedBytecodeFormatVersion = 21;
 
   enum Opcode {
 #define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,
@@ -981,6 +981,8 @@
       case KernelBytecode::kDebugCheck:
       case KernelBytecode::kDirectCall:
       case KernelBytecode::kDirectCall_Wide:
+      case KernelBytecode::kUncheckedDirectCall:
+      case KernelBytecode::kUncheckedDirectCall_Wide:
       case KernelBytecode::kInterfaceCall:
       case KernelBytecode::kInterfaceCall_Wide:
       case KernelBytecode::kInstantiatedInterfaceCall:
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index c771da7..4a89518 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -729,28 +729,45 @@
   if (FLAG_print_llvm_constant_pool) {
     StackZone printing_zone(T);
     HandleScope printing_scope(T);
-    const auto& arr =
+    TextBuffer b(1000);
+    const auto& constants =
         GrowableObjectArray::Handle(I->object_store()->llvm_constant_pool());
-    if (arr.IsNull()) {
-      THR_Print("No constant pool information in snapshot.\n");
+    if (constants.IsNull()) {
+      b.AddString("No constant pool information in snapshot.\n\n");
     } else {
-      auto const len = arr.Length();
-      THR_Print("Constant pool contents (length %" Pd "):\n", len);
+      auto const len = constants.Length();
+      b.Printf("Constant pool contents (length %" Pd "):\n", len);
       auto& obj = Object::Handle();
       for (intptr_t i = 0; i < len; i++) {
-        obj = arr.At(i);
-        THR_Print("  %5" Pd ": ", i);
+        obj = constants.At(i);
+        b.Printf("  %5" Pd ": ", i);
         if (obj.IsString()) {
-          auto& str = String::Cast(obj);
-          TextBuffer b(100);
-          b.AddEscapedString(str.ToCString());
-          THR_Print("\"%s\"\n", b.buf());
+          b.AddChar('"');
+          b.AddEscapedString(obj.ToCString());
+          b.AddChar('"');
         } else {
-          THR_Print("%s\n", obj.ToCString());
+          b.AddString(obj.ToCString());
         }
+        b.AddChar('\n');
       }
-      THR_Print("End of constant pool.\n\n");
+      b.AddString("End of constant pool.\n\n");
     }
+    const auto& functions =
+        GrowableObjectArray::Handle(I->object_store()->llvm_function_pool());
+    if (functions.IsNull()) {
+      b.AddString("No function pool information in snapshot.\n\n");
+    } else {
+      auto const len = functions.Length();
+      b.Printf("Function pool contents (length %" Pd "):\n", len);
+      auto& obj = Function::Handle();
+      for (intptr_t i = 0; i < len; i++) {
+        obj ^= functions.At(i);
+        ASSERT(!obj.IsNull());
+        b.Printf("  %5" Pd ": %s\n", i, obj.ToFullyQualifiedCString());
+      }
+      b.AddString("End of function pool.\n\n");
+    }
+    THR_Print("%s", b.buf());
   }
 #else
   // JIT: The megamorphic miss function and code come from the snapshot in JIT
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 749f567..2f26ce6 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -39,14 +39,7 @@
  public:
   NO_SANITIZE_SAFE_STACK
   explicit ScopedIsolateStackLimits(Thread* thread, uword current_sp)
-      : thread_(thread),
-#if defined(USING_SAFE_STACK)
-        saved_stack_limit_(0),
-        saved_safestack_limit_(0)
-#else
-        saved_stack_limit_(0)
-#endif
-  {
+      : thread_(thread) {
     ASSERT(thread != NULL);
     // Set the thread's stack_base based on the current
     // stack pointer, we keep refining this value as we
@@ -85,10 +78,10 @@
 
  private:
   Thread* thread_;
-  uword saved_stack_limit_;
 #if defined(USING_SAFE_STACK)
-  uword saved_safestack_limit_;
+  uword saved_safestack_limit_ = 0;
 #endif
+  uword saved_stack_limit_ = 0;
 };
 
 // Clears/restores Thread::long_jump_base on construction/destruction.
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index aa3fd63..0f54abd 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -625,6 +625,10 @@
   OSThread::SetCurrentSafestackPointer(saved_ssp);
 #endif
 
+#if defined(USING_SHADOW_CALL_STACK)
+  // The shadow call stack register will be restored by the JumpToFrame stub.
+#endif
+
   func(program_counter, stack_pointer, frame_pointer, thread);
 #endif
   UNREACHABLE();
@@ -1005,12 +1009,6 @@
   Exceptions::ThrowByType(Exceptions::kUnsupported, args);
 }
 
-void Exceptions::ThrowRangeErrorMsg(const char* msg) {
-  const Array& args = Array::Handle(Array::New(1));
-  args.SetAt(0, String::Handle(String::New(msg)));
-  Exceptions::ThrowByType(Exceptions::kRangeMsg, args);
-}
-
 void Exceptions::ThrowCompileTimeError(const LanguageError& error) {
   const Array& args = Array::Handle(Array::New(1));
   args.SetAt(0, String::Handle(error.FormatMessage()));
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 50d1a8f..d0a44d7 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -83,7 +83,6 @@
                                             const Integer& argument_value,
                                             intptr_t expected_from,
                                             intptr_t expected_to);
-  DART_NORETURN static void ThrowRangeErrorMsg(const char* msg);
   DART_NORETURN static void ThrowUnsupportedError(const char* msg);
   DART_NORETURN static void ThrowCompileTimeError(const LanguageError& error);
 
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index a926493..2649ca0 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -189,7 +189,7 @@
   const intptr_t len_in_bytes =
       Utils::RoundUp(len_in_bits, kBitsPerByte) / kBitsPerByte;
   const intptr_t unrounded_size_in_bytes =
-      3 * compiler::target::kWordSize + len_in_bytes;
+      2 * compiler::target::kWordSize + len_in_bytes;
   return Utils::RoundUp(unrounded_size_in_bytes,
                         compiler::target::ObjectAlignment::kObjectAlignment);
 }
@@ -443,7 +443,6 @@
       marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
 
       stream->WriteTargetWord(marked_tags);
-      stream->WriteFixed<uint32_t>(map.PcOffset());
       stream->WriteFixed<uint16_t>(map.Length());
       stream->WriteFixed<uint16_t>(map.SlowPathBitCount());
       stream->WriteBytes(map.raw()->ptr()->data(), len_in_bytes);
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index a46aa0f..d0de7f3 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -262,6 +262,9 @@
                                           intptr_t class_id,
                                           intptr_t instance_size,
                                           RawObject** result) {
+  ASSERT(instance_size > 0);
+  ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
+
   const uword start = thread->top();
 #ifndef PRODUCT
   auto table = thread->isolate()->shared_class_table();
@@ -269,7 +272,8 @@
     return false;
   }
 #endif
-  if (LIKELY((start + instance_size) < thread->end())) {
+  const intptr_t remaining = thread->end() - start;
+  if (LIKELY(remaining >= instance_size)) {
     thread->set_top(start + instance_size);
 #ifndef PRODUCT
     table->UpdateAllocatedNew(class_id, instance_size);
@@ -1848,6 +1852,27 @@
   }
 
   {
+    BYTECODE(UncheckedDirectCall, D_F);
+    DEBUG_CHECK;
+    // Invoke target function.
+    {
+      const uint32_t argc = rF;
+      const uint32_t kidx = rD;
+
+      InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
+      *++SP = LOAD_CONSTANT(kidx);
+      RawObject** call_base = SP - argc;
+      RawObject** call_top = SP;
+      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
+      if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
+        HANDLE_EXCEPTION;
+      }
+    }
+
+    DISPATCH();
+  }
+
+  {
     BYTECODE(InterfaceCall, D_F);
     DEBUG_CHECK;
     {
@@ -2673,6 +2698,19 @@
   }
 
   {
+    BYTECODE(CheckReceiverForNull, D);
+    SP -= 1;
+
+    if (UNLIKELY(SP[0] == null_value)) {
+      // Load selector.
+      SP[0] = LOAD_CONSTANT(rD);
+      goto ThrowNullError;
+    }
+
+    DISPATCH();
+  }
+
+  {
     BYTECODE(NegateInt, 0);
     DEBUG_CHECK;
     UNBOX_INT64(value, SP[0], Symbols::UnaryMinus());
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 103ce15..abf3f55 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -4,7 +4,6 @@
 
 #include "vm/kernel_isolate.h"
 
-#include "bin/dartutils.h"
 #include "include/dart_native_api.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_api_impl.h"
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e06b85a..e5cdec3 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -12831,9 +12831,7 @@
   }
 }
 
-RawStackMap* StackMap::New(intptr_t pc_offset,
-                           BitmapBuilder* bmap,
-                           intptr_t slow_path_bit_count) {
+RawStackMap* StackMap::New(BitmapBuilder* bmap, intptr_t slow_path_bit_count) {
   ASSERT(Object::stackmap_class() != Class::null());
   ASSERT(bmap != NULL);
   StackMap& result = StackMap::Handle();
@@ -12860,8 +12858,6 @@
     result ^= raw;
     result.SetLength(length);
   }
-  ASSERT(pc_offset >= 0);
-  result.SetPcOffset(pc_offset);
   if (payload_size > 0) {
     // Ensure leftover bits are deterministic.
     result.raw()->ptr()->data()[payload_size - 1] = 0;
@@ -12873,64 +12869,23 @@
   return result.raw();
 }
 
-RawStackMap* StackMap::New(intptr_t length,
-                           intptr_t slow_path_bit_count,
-                           intptr_t pc_offset) {
-  ASSERT(Object::stackmap_class() != Class::null());
-  StackMap& result = StackMap::Handle();
-  // Guard against integer overflow of the instance size computation.
-  intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte;
-  if ((length < 0) || (length > kMaxUint16) ||
-      (payload_size > kMaxLengthInBytes)) {
-    // This should be caught before we reach here.
-    FATAL1("Fatal error in StackMap::New: invalid length %" Pd "\n", length);
-  }
-  if ((slow_path_bit_count < 0) || (slow_path_bit_count > kMaxUint16)) {
-    // This should be caught before we reach here.
-    FATAL1("Fatal error in StackMap::New: invalid slow_path_bit_count %" Pd
-           "\n",
-           slow_path_bit_count);
-  }
-
-  {
-    // StackMap data objects are associated with a code object, allocate them
-    // in old generation.
-    RawObject* raw = Object::Allocate(
-        StackMap::kClassId, StackMap::InstanceSize(length), Heap::kOld);
-    NoSafepointScope no_safepoint;
-    result ^= raw;
-    result.SetLength(length);
-  }
-  ASSERT(pc_offset >= 0);
-  result.SetPcOffset(pc_offset);
-  result.SetSlowPathBitCount(slow_path_bit_count);
-  return result.raw();
-}
-
 const char* StackMap::ToCString() const {
-#define FORMAT "%#05x: "
-  if (IsNull()) {
-    return "{null}";
-  } else {
-    intptr_t fixed_length = Utils::SNPrint(NULL, 0, FORMAT, PcOffset()) + 1;
-    Thread* thread = Thread::Current();
-    // Guard against integer overflow in the computation of alloc_size.
-    //
-    // TODO(kmillikin): We could just truncate the string if someone
-    // tries to print a 2 billion plus entry stackmap.
-    if (Length() > (kIntptrMax - fixed_length)) {
-      FATAL1("Length() is unexpectedly large (%" Pd ")", Length());
-    }
-    intptr_t alloc_size = fixed_length + Length();
-    char* chars = thread->zone()->Alloc<char>(alloc_size);
-    intptr_t index = Utils::SNPrint(chars, alloc_size, FORMAT, PcOffset());
-    for (intptr_t i = 0; i < Length(); i++) {
-      chars[index++] = IsObject(i) ? '1' : '0';
-    }
-    chars[index] = '\0';
-    return chars;
+  if (IsNull()) return "{null}";
+  // Guard against integer overflow in the computation of alloc_size.
+  //
+  // TODO(kmillikin): We could just truncate the string if someone
+  // tries to print a 2 billion plus entry stackmap.
+  if (Length() > kIntptrMax) {
+    FATAL1("Length() is unexpectedly large (%" Pd ")", Length());
   }
-#undef FORMAT
+  Thread* thread = Thread::Current();
+  intptr_t alloc_size = Length() + 1;
+  char* chars = thread->zone()->Alloc<char>(alloc_size);
+  for (intptr_t i = 0; i < Length(); i++) {
+    chars[i] = IsObject(i) ? '1' : '0';
+  }
+  chars[alloc_size - 1] = '\0';
+  return chars;
 }
 
 RawString* LocalVarDescriptors::GetName(intptr_t var_index) const {
@@ -15178,12 +15133,15 @@
   // frame slots which are marked as having objects.
   *maps = stackmaps();
   *map = StackMap::null();
-  for (intptr_t i = 0; i < maps->Length(); i++) {
-    *map ^= maps->At(i);
+  for (intptr_t i = 0; i < maps->Length(); i += 2) {
+    // The reinterpret_cast from Smi::RawCast is inlined here because in
+    // debug mode, it creates Handles due to the ASSERT.
+    const uint32_t offset =
+        ValueFromRawSmi(reinterpret_cast<RawSmi*>(maps->At(i)));
+    if (offset != pc_offset) continue;
+    *map ^= maps->At(i + 1);
     ASSERT(!map->IsNull());
-    if (map->PcOffset() == pc_offset) {
-      return map->raw();  // We found a stack map for this frame.
-    }
+    return map->raw();
   }
   // If we are missing a stack map, this must either be unoptimized code, or
   // the entry to an osr function. (In which case all stack slots are
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 81bc595..c9daae0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5095,12 +5095,6 @@
 
   intptr_t Length() const { return raw_ptr()->length_; }
 
-  uint32_t PcOffset() const { return raw_ptr()->pc_offset_; }
-  void SetPcOffset(uint32_t value) const {
-    ASSERT(value <= kMaxUint32);
-    StoreNonPointer(&raw_ptr()->pc_offset_, value);
-  }
-
   intptr_t SlowPathBitCount() const { return raw_ptr()->slow_path_bit_count_; }
   void SetSlowPathBitCount(intptr_t bit_count) const {
     ASSERT(bit_count <= kMaxUint16);
@@ -5132,13 +5126,7 @@
   static intptr_t InstanceSize(intptr_t length) {
     return RoundedAllocationSize(UnroundedSize(length));
   }
-  static RawStackMap* New(intptr_t pc_offset,
-                          BitmapBuilder* bmap,
-                          intptr_t register_bit_count);
-
-  static RawStackMap* New(intptr_t length,
-                          intptr_t register_bit_count,
-                          intptr_t pc_offset);
+  static RawStackMap* New(BitmapBuilder* bmap, intptr_t slow_path_bit_count);
 
  private:
   void SetLength(intptr_t length) const {
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 221a326..3a6e3e5 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -125,6 +125,7 @@
   RW(Function, complete_on_async_return)                                       \
   RW(Class, async_star_stream_controller)                                      \
   RW(GrowableObjectArray, llvm_constant_pool)                                  \
+  RW(GrowableObjectArray, llvm_function_pool)                                  \
   RW(Array, llvm_constant_hash_table)                                          \
   RW(ObjectPool, global_object_pool)                                           \
   RW(Array, unique_dynamic_targets)                                            \
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 8592a76..f748ed2 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1835,10 +1835,22 @@
 TEST_CASE(ArrayLengthSmiMin) {
   TestIllegalArrayLength(kSmiMin);
 }
+
 TEST_CASE(ArrayLengthOneTooMany) {
   const intptr_t kOneTooMany = Array::kMaxElements + 1;
   ASSERT(kOneTooMany >= 0);
-  TestIllegalArrayLength(kOneTooMany);
+
+  char buffer[1024];
+  Utils::SNPrint(buffer, sizeof(buffer),
+                 "main() {\n"
+                 "  return new List(%" Pd
+                 ");\n"
+                 "}\n",
+                 kOneTooMany);
+  Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
+  EXPECT_VALID(lib);
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_ERROR(result, "Out of Memory");
 }
 
 TEST_CASE(ArrayLengthMaxElements) {
@@ -1876,7 +1888,7 @@
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
   Utils::SNPrint(buffer, sizeof(buffer), "%" Pd, length);
-  EXPECT_ERROR(result, "Invalid argument(s)");
+  EXPECT_ERROR(result, "RangeError (length): Invalid value");
   EXPECT_ERROR(result, buffer);
 }
 
@@ -1890,7 +1902,19 @@
   const intptr_t kOneTooMany =
       TypedData::MaxElements(kTypedDataInt8ArrayCid) + 1;
   ASSERT(kOneTooMany >= 0);
-  TestIllegalTypedDataLength("Int8List", kOneTooMany);
+
+  char buffer[1024];
+  Utils::SNPrint(buffer, sizeof(buffer),
+                 "import 'dart:typed_data';\n"
+                 "main() {\n"
+                 "  return new Int8List(%" Pd
+                 ");\n"
+                 "}\n",
+                 kOneTooMany);
+  Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
+  EXPECT_VALID(lib);
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_ERROR(result, "Out of Memory");
 }
 
 TEST_CASE(Int8ListLengthMaxElements) {
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 4eaae29..2641103 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -8,9 +8,14 @@
 #include "vm/os.h"
 
 #include <errno.h>
-#if !defined(FUCHSIA_SDK)
+#if defined(FUCHSIA_SDK)
+#include <fuchsia/deprecatedtimezone/cpp/fidl.h>
+namespace fuchsia {
+namespace timezone = deprecatedtimezone;
+}
+#else
 #include <fuchsia/timezone/cpp/fidl.h>
-#endif  //  !defined(FUCHSIA_SDK)
+#endif  //  defined(FUCHSIA_SDK)
 #include <lib/sys/cpp/service_directory.h>
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
@@ -39,7 +44,6 @@
   return static_cast<intptr_t>(getpid());
 }
 
-#if !defined(FUCHSIA_SDK)
 // TODO(FL-98): Change this to talk to fuchsia.dart to get timezone service to
 // directly get timezone.
 //
@@ -47,12 +51,10 @@
 // component:ConnectToEnvironmentServices and this is the only thing that is
 // blocking it and FL-98 will take time.
 static fuchsia::timezone::TimezoneSyncPtr tz;
-#endif  //  !defined(FUCHSIA_SDK)
 
 static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
                                                  int32_t* local_offset,
                                                  int32_t* dst_offset) {
-#if !defined(FUCHSIA_SDK)
   zx_status_t status = tz->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000,
                                                     local_offset, dst_offset);
   if (status != ZX_OK) {
@@ -61,13 +63,9 @@
   *local_offset *= 60;
   *dst_offset *= 60;
   return ZX_OK;
-#else
-  return ZX_ERR_NOT_SUPPORTED;
-#endif  //  !defined(FUCHSIA_SDK)
 }
 
 const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
-#if !defined(FUCHSIA_SDK)
   // TODO(abarth): Handle time zone changes.
   static const auto* tz_name = new std::string([] {
     std::string result;
@@ -75,9 +73,6 @@
     return result;
   }());
   return tz_name->c_str();
-#else
-  return "";
-#endif  //  !defined(FUCHSIA_SDK)}
 }
 
 int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
@@ -274,10 +269,8 @@
 }
 
 void OS::Init() {
-#if !defined(FUCHSIA_SDK)
   auto services = sys::ServiceDirectory::CreateFromNamespace();
   services->Connect(tz.NewRequest());
-#endif  //  !defined(FUCHSIA_SDK)
 }
 
 void OS::Cleanup() {}
diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc
index 01b2fe7..bf2469a 100644
--- a/runtime/vm/os_thread_fuchsia.cc
+++ b/runtime/vm/os_thread_fuchsia.cc
@@ -13,6 +13,7 @@
 #include <zircon/status.h>
 #include <zircon/syscalls.h>
 #include <zircon/threads.h>
+#include <zircon/tls.h>
 #include <zircon/types.h>
 
 #include "platform/address_sanitizer.h"
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 91c0267..55d1d56 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -212,7 +212,11 @@
 
   static Value ValueOf(Pair kv) { return kv; }
 
-  static inline intptr_t Hashcode(Key key) { return key->PcOffset(); }
+  static inline intptr_t Hashcode(Key key) {
+    intptr_t hash = key->SlowPathBitCount();
+    hash = CombineHashes(hash, key->Length());
+    return FinalizeHash(hash, kBitsPerWord - 1);
+  }
 
   static inline bool IsKeyEqual(Pair pair, Key key) {
     return pair->Equals(*key);
@@ -242,7 +246,7 @@
       code_ = function.CurrentCode();
       stackmaps_ = code_.stackmaps();
       if (stackmaps_.IsNull()) return;
-      for (intptr_t i = 0; i < stackmaps_.Length(); i++) {
+      for (intptr_t i = 1; i < stackmaps_.Length(); i += 2) {
         stackmap_ ^= stackmaps_.At(i);
         stackmap_ = DedupStackMap(stackmap_);
         stackmaps_.SetAt(i, stackmap_);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 9a33d1b..a3a0594 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1367,6 +1367,8 @@
     RawTypedData* catch_entry_moves_maps_;
     RawSmi* variables_;
   } catch_entry_;
+  // The stackmaps_ array contains alternating Smi and StackMap values, where
+  // each Smi value is the PC offset for the following StackMap value.
   RawArray* stackmaps_;
   RawArray* inlined_id_to_function_;
   RawCodeSourceMap* code_source_map_;
@@ -1620,10 +1622,6 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(StackMap);
   VISIT_NOTHING();
 
-  // Offset from code entry point corresponding to this stack map
-  // representation.
-  uint32_t pc_offset_;
-
   uint16_t length_;               // Length of payload, in bits.
   uint16_t slow_path_bit_count_;  // Slow path live values, included in length_.
   // ARM64 requires register_bit_count_ to be as large as 96.
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 3641e8a..4a5d757 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -248,29 +248,29 @@
     args.SetAt(2, String::Handle(zone, String::New("is not an integer")));
     Exceptions::ThrowByType(Exceptions::kArgumentValue, args);
   }
-  if (length.IsSmi()) {
-    const intptr_t len = Smi::Cast(length).Value();
-    if (Array::IsValidLength(len)) {
-      const Array& array = Array::Handle(zone, Array::New(len, Heap::kNew));
-      arguments.SetReturn(array);
-      TypeArguments& element_type =
-          TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
-      // An Array is raw or takes one type argument. However, its type argument
-      // vector may be longer than 1 due to a type optimization reusing the type
-      // argument vector of the instantiator.
-      ASSERT(element_type.IsNull() ||
-             (element_type.Length() >= 1 && element_type.IsInstantiated()));
-      array.SetTypeArguments(element_type);  // May be null.
-      return;
-    }
+  const int64_t len = Integer::Cast(length).AsInt64Value();
+  if (len < 0) {
+    // Throw: new RangeError.range(length, 0, Array::kMaxElements, "length");
+    Exceptions::ThrowRangeError("length", Integer::Cast(length), 0,
+                                Array::kMaxElements);
   }
-  // Throw: new RangeError.range(length, 0, Array::kMaxElements, "length");
-  const Array& args = Array::Handle(zone, Array::New(4));
-  args.SetAt(0, length);
-  args.SetAt(1, Integer::Handle(zone, Integer::New(0)));
-  args.SetAt(2, Integer::Handle(zone, Integer::New(Array::kMaxElements)));
-  args.SetAt(3, Symbols::Length());
-  Exceptions::ThrowByType(Exceptions::kRange, args);
+  if (len > Array::kMaxElements) {
+    const Instance& exception = Instance::Handle(
+        zone, thread->isolate()->object_store()->out_of_memory());
+    Exceptions::Throw(thread, exception);
+  }
+
+  const Array& array =
+      Array::Handle(zone, Array::New(static_cast<intptr_t>(len), Heap::kNew));
+  arguments.SetReturn(array);
+  TypeArguments& element_type =
+      TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
+  // An Array is raw or takes one type argument. However, its type argument
+  // vector may be longer than 1 due to a type optimization reusing the type
+  // argument vector of the instantiator.
+  ASSERT(element_type.IsNull() ||
+         (element_type.Length() >= 1 && element_type.IsInstantiated()));
+  array.SetTypeArguments(element_type);  // May be null.
 }
 
 // Helper returning the token position of the Dart caller.
@@ -630,6 +630,10 @@
   }
   const intptr_t len = new_cache.NumberOfChecks();
   if (len >= FLAG_max_subtype_cache_entries) {
+    if (FLAG_trace_type_checks) {
+      OS::PrintErr("Not updating subtype test cache as its length reached %d\n",
+                   FLAG_max_subtype_cache_entries);
+    }
     return;
   }
 #if defined(DEBUG)
@@ -834,10 +838,37 @@
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32) &&                 \
     !defined(DART_PRECOMPILED_RUNTIME)
   if (mode == kTypeCheckFromLazySpecializeStub) {
+    if (FLAG_trace_type_checks) {
+      OS::PrintErr("  Specializing type testing stub for %s\n",
+                   dst_type.ToCString());
+    }
     TypeTestingStubGenerator::SpecializeStubFor(thread, dst_type);
     // Only create the cache when we come from a normal stub.
     should_update_cache = false;
   }
+
+  // Fast path of type testing stub wasn't able to handle given type, yet it
+  // passed the type check. It means that fast-path was using outdated cid
+  // ranges and new classes appeared since the stub was generated.
+  // Re-generate the stub.
+  if ((mode == kTypeCheckFromSlowStub) && dst_type.IsType() &&
+      (TypeTestingStubGenerator::DefaultCodeForType(dst_type, /*lazy=*/false) !=
+       dst_type.type_test_stub()) &&
+      dst_type.IsInstantiated()) {
+    if (FLAG_trace_type_checks) {
+      OS::PrintErr("  Rebuilding type testing stub for %s\n",
+                   dst_type.ToCString());
+    }
+#if defined(DEBUG)
+    const auto& old_code = Code::Handle(dst_type.type_test_stub());
+#endif
+    TypeTestingStubGenerator::SpecializeStubFor(thread, dst_type);
+#if defined(DEBUG)
+    ASSERT(old_code.raw() != dst_type.type_test_stub());
+#endif
+    // Only create the cache when we come from a normal stub.
+    should_update_cache = false;
+  }
 #endif
 
   if (should_update_cache) {
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 24197fe..ea0a4a4 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -2234,6 +2234,12 @@
   if (instr->IsDivision()) {
     DoDivision(instr);
     return;
+  } else if (instr->IsRbit()) {
+    // Format(instr, "rbit'cond 'rd, 'rm");
+    Register rm = instr->RmField();
+    Register rd = instr->RdField();
+    set_register(rd, Utils::ReverseBits32(get_register(rm)));
+    return;
   }
   Register rd = instr->RdField();
   Register rn = instr->RnField();
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 8eb8dd5..efc5e89 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -886,7 +886,10 @@
                              R31Type r31t) {
   // Register is in range.
   ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
+#if !defined(TARGET_OS_FUCHSIA)
   ASSERT(instr == NULL || reg != R18);  // R18 is globally reserved on iOS.
+#endif
+
   if ((reg != R31) || (r31t != R31IsZR)) {
     registers_[reg] = value;
     // If we're setting CSP, make sure it is 16-byte aligned. In truth, CSP
@@ -2434,6 +2437,17 @@
       }
       break;
     }
+    case 0: {
+      // Format(instr, "rbit'sf 'rd, 'rn");
+      if (instr->SFField() == 1) {
+        const uint64_t rd_val = Utils::ReverseBits64(rn_val64);
+        set_register(instr, rd, rd_val, R31IsZR);
+      } else {
+        const uint32_t rd_val = Utils::ReverseBits32(rn_val32);
+        set_wregister(rd, rd_val, R31IsZR);
+      }
+      break;
+    }
     default:
       UnimplementedInstruction(instr);
       break;
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index 1558a22..7a5cfc5 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -49,8 +49,13 @@
 static const int kLastParamSlotFromEntrySp = 0;
 
 // Entry and exit frame layout.
+#if defined(TARGET_OS_FUCHSIA)
+static const int kExitLinkSlotFromEntryFp = -23;
+COMPILE_ASSERT(kAbiPreservedCpuRegCount == 11);
+#else
 static const int kExitLinkSlotFromEntryFp = -22;
 COMPILE_ASSERT(kAbiPreservedCpuRegCount == 10);
+#endif
 COMPILE_ASSERT(kAbiPreservedFpuRegCount == 8);
 
 // For FFI native -> Dart callbacks, this is the number of stack slots between
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index b1fa522..a982438 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -287,6 +287,9 @@
     saved_safestack_limit_ = limit;
   }
 #endif
+  static uword saved_shadow_call_stack_offset() {
+    return OFFSET_OF(Thread, saved_shadow_call_stack_);
+  }
 
 #if defined(TARGET_ARCH_DBC)
   // Access to the current stack limit for DBC interpreter.
@@ -892,6 +895,7 @@
   RawObject* active_stacktrace_;
   RawObjectPool* global_object_pool_;
   uword resume_pc_;
+  uword saved_shadow_call_stack_ = 0;
   uword execution_state_;
   uword safepoint_state_;
   RawGrowableObjectArray* ffi_callback_code_;
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 1bce4cc..5805581 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -53,7 +53,6 @@
   V(Embedder, "dart:embedder")                                                 \
   V(GC, "dart:gc")                                                             \
   V(Isolate, "dart:isolate")                                                   \
-  V(Developer, "dart:developer")                                               \
   V(VM, "dart:vm")
 
 // A stream of timeline events. A stream has a name and can be enabled or
diff --git a/runtime/vm/utils_test.cc b/runtime/vm/utils_test.cc
index 59d4b24..03e18ef 100644
--- a/runtime/vm/utils_test.cc
+++ b/runtime/vm/utils_test.cc
@@ -160,6 +160,22 @@
   EXPECT_EQ(0, Utils::CountLeadingZeros(kTopBit));
 }
 
+VM_UNIT_TEST_CASE(ReverseBits32) {
+  EXPECT_EQ(0xffffffffU, Utils::ReverseBits32(0xffffffffU));
+  EXPECT_EQ(0xf0000000U, Utils::ReverseBits32(0x0000000fU));
+  EXPECT_EQ(0x00000001U, Utils::ReverseBits32(0x80000000U));
+  EXPECT_EQ(0x22222222U, Utils::ReverseBits32(0x44444444U));
+  EXPECT_EQ(0x1E6A2C48U, Utils::ReverseBits32(0x12345678U));
+}
+
+VM_UNIT_TEST_CASE(ReverseBits64) {
+  EXPECT_EQ(0xffffffffffffffffLLU, Utils::ReverseBits64(0xffffffffffffffffLLU));
+  EXPECT_EQ(0xf000000000000000LLU, Utils::ReverseBits64(0x000000000000000fLLU));
+  EXPECT_EQ(0x0000000000000001LLU, Utils::ReverseBits64(0x8000000000000000LLU));
+  EXPECT_EQ(0x2222222222222222LLU, Utils::ReverseBits64(0x4444444444444444LLU));
+  EXPECT_EQ(0x8f7b3d591e6a2c48LLU, Utils::ReverseBits64(0x123456789abcdef1LLU));
+}
+
 VM_UNIT_TEST_CASE(IsInt) {
   EXPECT(Utils::IsInt(8, 16));
   EXPECT(Utils::IsInt(8, 127));
diff --git a/sdk/lib/_internal/vm/lib/wasm_patch.dart b/sdk/lib/_internal/vm/lib/wasm_patch.dart
index 5ae21c4..1372932 100644
--- a/sdk/lib/_internal/vm/lib/wasm_patch.dart
+++ b/sdk/lib/_internal/vm/lib/wasm_patch.dart
@@ -112,6 +112,11 @@
     _buffer = _init(initialPages, maxPages);
   }
 
+  _NativeWasmMemory.fromInstance(_NativeWasmInstance inst) {
+    _buffer = _initFromInstance(inst);
+    _pages = _getPages();
+  }
+
   int get lengthInPages => _pages;
   int get lengthInBytes => _buffer.lengthInBytes;
   int operator [](int index) => _buffer[index];
@@ -128,6 +133,9 @@
 
   Uint8List _init(int initialPages, int maxPages) native 'Wasm_initMemory';
   Uint8List _grow(int deltaPages) native 'Wasm_growMemory';
+  Uint8List _initFromInstance(_NativeWasmInstance inst)
+      native 'Wasm_initMemoryFromInstance';
+  int _getPages() native 'Wasm_getMemoryPages';
 }
 
 class _NativeWasmInstance extends NativeFieldWrapperClass1
@@ -145,6 +153,10 @@
     return _NativeWasmFunction<T>(this, name);
   }
 
+  WasmMemory get memory {
+    return _NativeWasmMemory.fromInstance(this);
+  }
+
   void _init(_NativeWasmModule module, _NativeWasmImports imports)
       native 'Wasm_initInstance';
 }
diff --git a/sdk/lib/core/exceptions.dart b/sdk/lib/core/exceptions.dart
index 2e137e5..27c11fa 100644
--- a/sdk/lib/core/exceptions.dart
+++ b/sdk/lib/core/exceptions.dart
@@ -13,9 +13,10 @@
  * so that the error can be addressed programmatically. It is intended to be
  * caught, and it should contain useful data fields.
  *
- * Creating instances of [Exception] directly with [:new Exception("message"):]
- * is discouraged, and only included as a temporary measure during development,
- * until the actual exceptions used by a library are done.
+ * Creating instances of [Exception] directly with `Exception("message")`
+ * is discouraged in library code since it doesn't give users a precise
+ * type they can catch. It may be reasonable to use instances of this
+ * class in tests or during development.
  */
 abstract class Exception {
   factory Exception([var message]) => _Exception(message);
diff --git a/sdk/lib/wasm/wasm.dart b/sdk/lib/wasm/wasm.dart
index f5814ca..0d123c2 100644
--- a/sdk/lib/wasm/wasm.dart
+++ b/sdk/lib/wasm/wasm.dart
@@ -80,6 +80,9 @@
 abstract class WasmInstance {
   // Find an exported function with the given signature.
   WasmFunction<T> lookupFunction<T extends Function>(String name);
+
+  // Returns this instances's memory.
+  WasmMemory get memory;
 }
 
 // WasmFunction is a callable function in a WasmInstance.
diff --git a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
index df3e33e..1e43d2c 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
@@ -114,6 +114,11 @@
     _buffer = _init(initialPages, maxPages);
   }
 
+  _NativeWasmMemory.fromInstance(_NativeWasmInstance inst) {
+    _buffer = _initFromInstance(inst);
+    _pages = _getPages();
+  }
+
   int get lengthInPages => _pages;
   int get lengthInBytes => _buffer.lengthInBytes;
   int operator [](int index) => _buffer[index];
@@ -130,6 +135,9 @@
 
   Uint8List _init(int initialPages, int maxPages) native 'Wasm_initMemory';
   Uint8List _grow(int deltaPages) native 'Wasm_growMemory';
+  Uint8List _initFromInstance(_NativeWasmInstance inst)
+      native 'Wasm_initMemoryFromInstance';
+  int _getPages() native 'Wasm_getMemoryPages';
 }
 
 class _NativeWasmInstance extends NativeFieldWrapperClass1
@@ -147,6 +155,10 @@
     return _NativeWasmFunction<T>(this, name);
   }
 
+  WasmMemory get memory {
+    return _NativeWasmMemory.fromInstance(this);
+  }
+
   void _init(_NativeWasmModule module, _NativeWasmImports imports)
       native 'Wasm_initInstance';
 }
diff --git a/sdk_nnbd/lib/core/exceptions.dart b/sdk_nnbd/lib/core/exceptions.dart
index 4ac5ace..38a5575 100644
--- a/sdk_nnbd/lib/core/exceptions.dart
+++ b/sdk_nnbd/lib/core/exceptions.dart
@@ -15,9 +15,10 @@
  * so that the error can be addressed programmatically. It is intended to be
  * caught, and it should contain useful data fields.
  *
- * Creating instances of [Exception] directly with [:new Exception("message"):]
- * is discouraged, and only included as a temporary measure during development,
- * until the actual exceptions used by a library are done.
+ * Creating instances of [Exception] directly with `Exception("message")`
+ * is discouraged in library code since it doesn't give users a precise
+ * type they can catch. It may be reasonable to use instances of this
+ * class in tests or during development.
  */
 abstract class Exception {
   factory Exception([var message]) => _Exception(message);
diff --git a/sdk_nnbd/lib/wasm/wasm.dart b/sdk_nnbd/lib/wasm/wasm.dart
index 4394189..f1c05c7 100644
--- a/sdk_nnbd/lib/wasm/wasm.dart
+++ b/sdk_nnbd/lib/wasm/wasm.dart
@@ -82,6 +82,9 @@
 abstract class WasmInstance {
   // Find an exported function with the given signature.
   WasmFunction<T> lookupFunction<T extends Function>(String name);
+
+  // Returns this instance's memory.
+  WasmMemory get memory;
 }
 
 // WasmFunction is a callable function in a WasmInstance.
diff --git a/tests/compiler/dart2js/analyses/analysis_helper.dart b/tests/compiler/dart2js/analyses/analysis_helper.dart
index 4b6234d..cea60ab 100644
--- a/tests/compiler/dart2js/analyses/analysis_helper.dart
+++ b/tests/compiler/dart2js/analyses/analysis_helper.dart
@@ -309,7 +309,9 @@
         node is! ir.Expression ||
             staticType == typeEnvironment.nullType ||
             typeEnvironment.isSubtypeOf(
-                staticType, _getStaticTypeFromExpression(node)),
+                staticType,
+                _getStaticTypeFromExpression(node),
+                ir.SubtypeCheckMode.ignoringNullabilities),
         reportAssertionFailure(
             node,
             "Unexpected static type for $node (${node.runtimeType}): "
diff --git a/tests/compiler/dart2js/equivalence/id_testing_test.dart b/tests/compiler/dart2js/equivalence/id_testing_test.dart
index a24168a..c40ff6f 100644
--- a/tests/compiler/dart2js/equivalence/id_testing_test.dart
+++ b/tests/compiler/dart2js/equivalence/id_testing_test.dart
@@ -61,7 +61,7 @@
     KernelToElementMapImpl elementMap = frontendStrategy.elementMap;
     ir.Library node = elementMap.getLibraryNode(library);
     new IdTestingDataExtractor(compiler.reporter, actualMap, elementMap)
-        .computeForLibrary(node, useFileUri: true);
+        .computeForLibrary(node);
   }
 
   @override
diff --git a/tests/compiler/dartdevc/modular/nnbd_subtype/main.dart b/tests/compiler/dartdevc/modular/nnbd_subtype/main.dart
new file mode 100644
index 0000000..fd89ae0
--- /dev/null
+++ b/tests/compiler/dartdevc/modular/nnbd_subtype/main.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:_runtime' as dart;
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D<T extends B> {}
+
+class E<T, S> {}
+
+class F extends E<B, B> {}
+
+// Returns sWrapped<tWrapped> as a wrapped type.
+Object generic1(Type sWrapped, Type tWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  var sGeneric = dart.getGenericClass(s);
+  return dart.wrapType(JS('', '#(#)', sGeneric, t));
+}
+
+// Returns sWrapped<tWrapped, rWrapped> as a wrapped type.
+Object generic2(Type sWrapped, Type tWrapped, Type rWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  var r = dart.unwrapType(rWrapped);
+  var sGeneric = dart.getGenericClass(s);
+  return dart.wrapType(JS('', '#(#, #)', sGeneric, t, r));
+}
+
+// Returns a function type of argWrapped -> returnWrapped as a wrapped type.
+Object function1(Type returnWrapped, Type argWrapped) {
+  var returnType = dart.unwrapType(returnWrapped);
+  var argType = dart.unwrapType(argWrapped);
+  var fun = dart.fnType(returnType, [argType]);
+  return dart.wrapType(fun);
+}
+
+// Returns a function type with a bounded type argument that takes no argument
+// and returns void as a wrapped type.
+Object genericFunction(Type boundWrapped) => dart.wrapType(dart.gFnType(
+    (T) => [dart.VoidType, []], (T) => [dart.unwrapType(boundWrapped)]));
+
+// Returns a function type with a bounded generic return type of
+// <T extends typeBoud> argWrapped -> T as a wrapped type.
+Object functionGenericReturn(Type boundWrapped, Type argWrapped) =>
+    dart.wrapType(dart.gFnType(
+        (T) => [
+              T,
+              [dart.unwrapType(argWrapped)]
+            ],
+        (T) => [dart.unwrapType(boundWrapped)]));
+
+// Returns a function with a bounded generic argument type of
+// <T extends typeBoud> T -> returnWrapped as a wrapped type.
+Object functionGenericArg(Type boundWrapped, Type returnWrapped) =>
+    dart.wrapType(dart.gFnType(
+        (T) => [
+              dart.unwrapType(returnWrapped),
+              [T]
+            ],
+        (T) => [dart.unwrapType(boundWrapped)]));
+
+void checkSubtype(Type sWrapped, Type tWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  Expect.isTrue(dart.isSubtypeOf(s, t), '$s should be subtype of $t.');
+}
+
+void checkProperSubtype(Type sWrapped, Type tWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  Expect.isTrue(dart.isSubtypeOf(s, t), '$s should be subtype of $t.');
+  Expect.isFalse(dart.isSubtypeOf(t, s), '$t should not be subtype of $s.');
+}
+
+void main() {
+  // A <: dynamic
+  checkProperSubtype(A, dynamic);
+  // A <: Object
+  checkProperSubtype(A, Object);
+  // TODO(nshahan) Test void as top? A <: void
+
+  // Null <: A
+  checkProperSubtype(Null, A);
+
+  // FutureOr<Null> <: Future<Null>
+  checkSubtype(generic1(FutureOr, Null), generic1(Future, Null));
+  // Future<B> <: FutureOr<A>
+  checkProperSubtype(generic1(Future, B), generic1(FutureOr, A));
+  // B <: <: FutureOr<A>
+  checkProperSubtype(B, generic1(FutureOr, A));
+  // Future<B> <: Future<A>
+  checkProperSubtype(generic1(Future, B), generic1(Future, A));
+  // B <: A
+  checkProperSubtype(B, A);
+
+  // A <: A
+  checkSubtype(A, A);
+  // C <: B
+  checkProperSubtype(C, B);
+  // C <: A
+  checkProperSubtype(C, A);
+
+  // A -> B <: Function
+  checkProperSubtype(function1(B, A), Function);
+
+  // A -> B <: A -> B
+  checkSubtype(function1(B, A), function1(B, A));
+
+  // A -> B <: B -> B
+  checkProperSubtype(function1(B, A), function1(B, B));
+  // TODO(nshahan) Subtype check with covariant keyword?
+
+  // A -> B <: A -> A
+  checkSubtype(function1(B, A), function1(A, A));
+
+  // Generic Function Subtypes.
+  // Bound is a built in type.
+  // <T extends int> void -> void <: <T extends int> void -> void
+  checkSubtype(genericFunction(int), genericFunction(int));
+
+  // <T extends String> A -> T <: <T extends String> B -> T
+  checkProperSubtype(
+      functionGenericReturn(String, A), functionGenericReturn(String, B));
+
+  // <T extends double> T -> B <: <T extends double> T -> A
+  checkProperSubtype(
+      functionGenericArg(double, B), functionGenericArg(double, A));
+
+  // Bound is a function type.
+  // <T extends A -> B> void -> void <: <T extends A -> B> void -> void
+  checkSubtype(
+      genericFunction(function1(B, A)), genericFunction(function1(B, A)));
+
+  // <T extends A -> B> A -> T <: <T extends A -> B> B -> T
+  checkProperSubtype(functionGenericReturn(function1(B, A), A),
+      functionGenericReturn(function1(B, A), B));
+
+  // <T extends A -> B> T -> B <: <T extends A -> B> T -> A
+  checkProperSubtype(functionGenericArg(function1(B, A), B),
+      functionGenericArg(function1(B, A), A));
+
+  // Bound is a user defined class.
+  // <T extends B> void -> void <: <T extends B> void -> void
+  checkSubtype(genericFunction(B), genericFunction(B));
+
+  // <T extends B> A -> T <: <T extends B> B -> T
+  checkProperSubtype(functionGenericReturn(B, A), functionGenericReturn(B, B));
+
+  // <T extends B> T -> B <: <T extends B> T -> A
+  checkProperSubtype(functionGenericArg(B, B), functionGenericArg(B, A));
+
+  // Bound is a Future.
+  // <T extends Future<B>> void -> void <: <T extends Future<B>> void -> void
+  checkSubtype(genericFunction(generic1(Future, B)),
+      genericFunction(generic1(Future, B)));
+
+  // <T extends Future<B>> A -> T <: <T extends Future<B>> B -> T
+  checkProperSubtype(functionGenericReturn(generic1(Future, B), A),
+      functionGenericReturn(generic1(Future, B), B));
+
+  // <T extends Future<B>> T -> B <: <T extends Future<B>> T -> A
+  checkProperSubtype(functionGenericArg(generic1(Future, B), B),
+      functionGenericArg(generic1(Future, B), A));
+
+  // Bound is a FutureOr.
+  // <T extends FutureOr<B>> void -> void <:
+  //    <T extends FutureOr<B>> void -> void
+  checkSubtype(genericFunction(generic1(FutureOr, B)),
+      genericFunction(generic1(FutureOr, B)));
+
+  // <T extends FutureOr<B>> A -> T <: <T extends FutureOr<B>> B -> T
+  checkProperSubtype(functionGenericReturn(generic1(FutureOr, B), A),
+      functionGenericReturn(generic1(FutureOr, B), B));
+
+  // <T extends FutureOr<B>> T -> B <: <T extends FutureOr<B>> T -> A
+  checkProperSubtype(functionGenericArg(generic1(FutureOr, B), B),
+      functionGenericArg(generic1(FutureOr, B), A));
+
+  // D <: D<B>
+  checkSubtype(D, generic1(D, B));
+  // D<B> <: D
+  checkSubtype(generic1(D, B), D);
+  // D<C> <: D<B>
+  checkProperSubtype(generic1(D, C), generic1(D, B));
+
+  // F <: E
+  checkProperSubtype(F, E);
+  // F <: E<A, A>
+  checkProperSubtype(F, generic2(E, A, A));
+  // // E<B, B> <: E<A, A>
+  checkProperSubtype(generic2(E, B, B), E);
+  // // E<B, B> <: E<A, A>
+  checkProperSubtype(generic2(E, B, B), generic2(E, A, A));
+}
diff --git a/tests/compiler/dartdevc/modular/nnbd_subtype/modules.yaml b/tests/compiler/dartdevc/modular/nnbd_subtype/modules.yaml
new file mode 100644
index 0000000..4843548
--- /dev/null
+++ b/tests/compiler/dartdevc/modular/nnbd_subtype/modules.yaml
@@ -0,0 +1,11 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# NNBD runtime subtype tests.
+# Temporarily here until the test/compiler/dartdevc_native suite is migrated for
+# nnbd.
+dependencies:
+  main: expect
+# flags:
+#   - non-nullable
\ No newline at end of file
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index f11deb7..2d8824e 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -2,58 +2,11 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == dart2analyzer ]
-num_sign_test: Crash, Pass # Issue 31768
-
-[ $compiler == dart2js ]
-bigint_from_test: RuntimeError # Issue 32589
-bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-core_runtime_types_test: RuntimeError # Issue 34147
-date_time11_test: RuntimeError, Pass # Fails when US is on winter time, issue 31285.
-double_ceil_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_floor_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-error_stack_trace1_test: RuntimeError # Issue 12399
-int_from_environment_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_parse_radix_int64_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_parse_radix_int64_test/02: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_parse_radix_int64_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_to_string_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-list_unmodifiable_test: Pass, RuntimeError # Issue 28712
-
 [ $compiler == dartdevk ]
 regexp/lookbehind_test/01: Skip # Flaky in uncatchable way.  Issue 36280
 
-[ $compiler == none ]
-symbol_operator_test/03: Fail # Issue 11669
-symbol_reserved_word_test/02: CompileTimeError # Issue 20191
-symbol_reserved_word_test/04: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/06: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_reserved_word_test/07: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/09: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_reserved_word_test/10: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/12: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_test/01: Fail, Pass # Issue 11669
-symbol_test/02: MissingCompileTimeError # Issue 11669
-symbol_test/03: MissingCompileTimeError # Issue 11669
-symbol_test/none: Fail # Issue 11669
-unicode_test: Fail # Issue 6706
-
 [ $mode == debug ]
-regexp/pcre_test: Pass, Slow # Issue 22008
-
-[ $runtime == jsshell ]
-string_case_test/01: Fail, OK # German double S.
-
-[ $runtime == safari ]
-double_round3_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
-double_round_to_double2_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
-string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
+regexp/pcre_test: Slow # Issue 22008
 
 [ $arch == simarmv5te && ($runtime == dart_precompiled || $runtime == vm) ]
 int_parse_radix_test/*: Slow
@@ -62,9 +15,6 @@
 [ $arch == x64 && $system == windows ]
 stopwatch_test: Skip # Flaky test due to expected performance behaviour.
 
-[ $builder_tag == obfuscated && $compiler == dartkp ]
-nsm_invocation_test: RuntimeError # Issue 35066
-
 [ $builder_tag == obfuscated && $runtime == dart_precompiled ]
 apply_generic_function_test: SkipByDesign # Function.apply with named args
 apply_test: Skip # Uses new Symbol via symbolMapToStringMap helper
@@ -72,60 +22,11 @@
 error_stack_trace1_test: SkipByDesign # Expects unobfuscated stack trace
 type_tostring_test: SkipByDesign # Expects names in Type.toString()
 
-[ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $runtime != none ]
-map_keys2_test: RuntimeError # needs Dart 2 is checks
-
 [ $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk ]
 bigint_js_test: SkipByDesign # JavaScript-specific test
 
-[ $compiler == dart2js && $runtime == chromeOnAndroid ]
-list_as_map_test: Pass, Slow # TODO(kasperl): Please triage.
-string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
-
-[ $compiler == dart2js && $runtime == d8 ]
-uri_base_test: RuntimeError # D8 uses a custom uri scheme for Uri.base
-
 [ $compiler == dart2js && $runtime != none ]
-regexp/pcre_test: Pass, Slow # Issue 21593
-
-[ $compiler == dart2js && !$browser ]
-package_resource_test: RuntimeError # Issue 26842
-
-[ $compiler == dart2js && $checked ]
-error_stack_trace1_test: RuntimeError # Issue 12399
-iterable_return_type_test/01: RuntimeError # Issue 20085
-iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-iterable_to_list_test/01: Crash # Wrong number of template arguments, given 2, expected 1
-iterable_to_list_test/none: Crash # Wrong number of template arguments, given 2, expected 1
-list_replace_range_test: RuntimeError # Issue 32010
-list_test/01: Crash # Unsupported operation: Unsupported type parameter type node T.
-list_test/none: Crash # Unsupported operation: Unsupported type parameter type node T.
-map_test: Crash # tests/corelib_2/map_test.dart:903:7: Internal problem: Unhandled Null in installDefaultConstructor.
-symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
-
-[ $compiler == dart2js && $minified ]
-error_stack_trace1_test: RuntimeError # Issue 12399
-hash_set_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(_CustomHashSet.#x), local(_CustomHashSet.#)) for j:closure_call(_CustomHashSet__CustomHashSet_closure.call).
-iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-list_concurrent_modify_test: RuntimeError # dart2js does not fully implement these
-nsm_invocation_test: RuntimeError # Symbols don't match due to minifiaction.
-symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
-
-[ $compiler == dartdevc && $runtime != none ]
-compare_to2_test: CompileTimeError # invalid test
-symbol_operator_test: RuntimeError # Issue 29921
-
-[ $compiler == dartkp && $runtime == dart_precompiled ]
-iterable_reduce_test/01: CompileTimeError # Issue 31533
-symbol_operator_test/03: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_reserved_word_test/06: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_reserved_word_test/09: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_reserved_word_test/12: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-unicode_test: RuntimeError # Issue 18061: German double S.
-
-[ $compiler == none && $runtime == vm ]
-iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
+regexp/pcre_test: Slow # Issue 21593
 
 # We no longer expect Dart2 tests to run with the standalone VM without the new
 # common front end, but for now we get better coverage by still running them in
@@ -134,32 +35,9 @@
 *: SkipByDesign
 
 [ $runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk) ]
-bit_twiddling_test/int64: RuntimeError, OK # Requires fixed-size int64 support.
-compare_to2_test: RuntimeError, OK # Requires fixed-size int64 support.
-double_ceil_test/int64: RuntimeError, OK # Requires fixed-size int64 support.
-double_floor_test/int64: RuntimeError, OK # Requires fixed-size int64 support.
-double_round_test/int64: RuntimeError, OK # Requires fixed-size int64 support.
-double_truncate_test/int64: RuntimeError, OK # Requires fixed-size int64 support.
-hash_set_test/01: RuntimeError # non JS number semantics - Issue 11551
-int_modulo_arith_test/modPow: RuntimeError # Issue 29921
 int_parse_with_limited_ints_test: Skip # Requires fixed-size int64 support.
-integer_arith_vm_test/modPow: RuntimeError # Issues 10245, 30170
-integer_parsed_arith_vm_test: RuntimeError # Issues 10245, 29921
-integer_parsed_div_rem_vm_test: RuntimeError # Issue 29921
-integer_parsed_mul_div_vm_test: RuntimeError # Issue 29921
-regress_r21715_test: RuntimeError # Requires fixed-size int64 support.
 typed_data_with_limited_ints_test: Skip # Requires fixed-size int64 support.
 
-# ===== dartk + vm status lines =====
-[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-iterable_reduce_test/01: CompileTimeError # Issue 31533
-symbol_operator_test/03: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_reserved_word_test/06: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_reserved_word_test/09: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_reserved_word_test/12: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
-unicode_test: RuntimeError # Issue 18061: German double S.
-
 [ ($arch == simdbc || $arch == simdbc64) && ($hot_reload || $hot_reload_rollback) ]
 uri_parse_test: SkipSlow
 
@@ -167,108 +45,24 @@
 bigint_parse_radix_test: Skip # Issue 31659
 bigint_test: Skip # Issue 31659
 
-[ $arch == simdbc || $arch == simdbc64 ]
-regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
-
 [ $compiler == dartdevc || $compiler == dartdevk ]
-bigint_from_test: RuntimeError # Issue 32589
 bigint_test/03: SkipSlow # modPow is very slow
 bigint_test/15: SkipSlow # modPow is very slow
-bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-compare_to2_test: RuntimeError # Issue 30170
-compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-date_time10_test: RuntimeError # Issue 29921
-date_time_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_ceil_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_floor_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-error_stack_trace_test/nullThrown: RuntimeError # .stackTrace not present for exception caught from 'throw null;'
-hash_set_test/01: RuntimeError # Issue 29921
-int_from_environment_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_modulo_arith_test/none: RuntimeError # Issue 29921
-int_parse_radix_int64_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_parse_radix_int64_test/02: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_parse_radix_int64_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_parse_radix_test/01: RuntimeError # Issue 29921
 int_parse_with_limited_ints_test: Skip # Requires fixed-size int64 support.
-integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_arith_vm_test/modPow: RuntimeError # Issue 30170
-integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_parsed_arith_vm_test: RuntimeError # Issue 29921
-integer_to_radix_string_test: RuntimeError # Issue 29921
-integer_to_string_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_to_string_test/01: RuntimeError # Issue 29921
-iterable_return_type_test/02: RuntimeError # Issue 29921
-list_concurrent_modify_test: RuntimeError # DDC uses ES6 array iterators so it does not issue this
-list_removeat_test: RuntimeError # Issue 29921
-main_test: RuntimeError # Issue 29921
-nan_infinity_test/01: RuntimeError # Issue 29921
-regexp/alternative-length-miscalculation_test: RuntimeError # Issue 29921
-regexp/ascii-regexp-subject_test: RuntimeError # Issue 29921
-regexp/bol-with-multiline_test: RuntimeError # Issue 29921
-regexp/capture-3_test: RuntimeError # Issue 29921
-regexp/char-insensitive_test: RuntimeError # Issue 29921
-regexp/character-match-out-of-order_test: RuntimeError # Issue 29921
-regexp/compile-crash_test: RuntimeError # Issue 29921
-regexp/default_arguments_test: RuntimeError # Issue 29921
-regexp/early-acid3-86_test: RuntimeError # Issue 29921
-regexp/ecma-regex-examples_test: RuntimeError # Issue 29921
-regexp/extended-characters-match_test: RuntimeError # Issue 29921
-regexp/extended-characters-more_test: RuntimeError # Issue 29921
-regexp/find-first-asserted_test: RuntimeError # Issue 29921
-regexp/invalid-range-in-class_test: RuntimeError # Issue 29921
-regexp/look-ahead_test: RuntimeError # Issue 29921
-regexp/loop-capture_test: RuntimeError # Issue 29921
-regexp/malformed-escapes_test: RuntimeError # Issue 29921
-regexp/many-brackets_test: RuntimeError # Issue 29921
-regexp/negative-special-characters_test: RuntimeError # Issue 29921
-regexp/no-extensions_test: RuntimeError # Issue 29921
-regexp/non-bmp_test: RuntimeError # Issue 29921
-regexp/non-capturing-backtracking_test: RuntimeError # Issue 29921
-regexp/non-capturing-groups_test: RuntimeError # Issue 29921
-regexp/non-character_test: RuntimeError # Issue 29921
-regexp/non-greedy-parentheses_test: RuntimeError # Issue 29921
-regexp/pcre-test-4_test: RuntimeError # Issue 29921
-regexp/quantified-assertions_test: RuntimeError # Issue 29921
-regexp/range-bound-ffff_test: RuntimeError # Issue 29921
-regexp/range-out-of-order_test: RuntimeError # Issue 29921
-regexp/ranges-and-escaped-hyphens_test: RuntimeError # Issue 29921
-regexp/regress-6-9-regexp_test: RuntimeError # Issue 29921
-regexp/regress-regexp-codeflush_test: RuntimeError # Issue 29921
-regexp/regress-regexp-construct-result_test: RuntimeError # Issue 29921
-regexp/repeat-match-waldemar_test: RuntimeError # Issue 29921
-regexp/results-cache_test: RuntimeError # Issue 29921
-regexp/stack-overflow2_test: RuntimeError # Issue 29921
-regexp/stack-overflow_test: RuntimeError # Issue 29921
-regexp/unicode-handling_test: RuntimeError # Issue 29921
-regexp/zero-length-alternatives_test: RuntimeError # Issue 29921
-regress_r21715_test: RuntimeError # Issue 29921
-string_operations_with_null_test: RuntimeError # Issue 29921
-symbol_operator_test/03: RuntimeError # Issue 29921
-symbol_reserved_word_test/06: RuntimeError # Issue 29921
-symbol_reserved_word_test/09: RuntimeError # Issue 29921
-symbol_reserved_word_test/12: RuntimeError # Issue 29921
-symbol_test/none: RuntimeError # Issue 29921
 typed_data_with_limited_ints_test: Skip # Requires fixed-size int64 support.
 uri_parse_test: Slow
 uri_test: Slow
 
 [ $compiler == dartkb || $compiler == dartkp ]
-bigint_parse_radix_test: Pass, Slow # --no_intrinsify
+bigint_parse_radix_test: Slow # --no_intrinsify
 bigint_test/03: SkipSlow # --no_intrinsify
 bigint_test/15: SkipSlow # --no_intrinsify
 
 [ $runtime == dart_precompiled || $runtime == vm ]
 regexp/global_test: Skip # Issue 21709
 regexp/pcre_test: Slow
-string_case_test/01: RuntimeError # Issue 18061: German double S.
-
-[ $runtime == ff || $runtime == jsshell ]
-double_parse_test: Fail, OK # Issue 30468
-double_try_parse_test: Fail, OK # Issue 30468
 
 [ $hot_reload || $hot_reload_rollback ]
 bigint_parse_radix_test: Skip # Issue 31659. Issue 34361.
 bigint_test: Skip # Issue 31659
-integer_parsed_mul_div_vm_test: Pass, Slow # Slow
+integer_parsed_mul_div_vm_test: Slow # Slow
diff --git a/tests/corelib_2/growable_list_test.dart b/tests/corelib_2/growable_list_test.dart
index 2172710..cea1446 100644
--- a/tests/corelib_2/growable_list_test.dart
+++ b/tests/corelib_2/growable_list_test.dart
@@ -91,7 +91,8 @@
   testGrowable(new List<int>.filled(5, null, growable: true));
   Expect.throwsArgumentError(() => new List<int>(-1), "-1");
   // There must be limits. Fix this test if we ever allow 2^63 elements.
-  Expect.throwsArgumentError(() => new List<int>(0x7ffffffffffff000), "bignum");
+  Expect.throws(() => new List<int>(0x7ffffffffffff000),
+      (e) => e is OutOfMemoryError || e is ArgumentError, "bignum");
   Expect.throwsArgumentError(() => new List<int>(null), "null");
   testThrowsOrTypeError(
       () => new List([] as Object), // Cast to avoid warning.
diff --git a/tests/ffi/enable_ffi_test.dart b/tests/ffi/enable_ffi_test.dart
index 1ccb5ec..167c25c 100644
--- a/tests/ffi/enable_ffi_test.dart
+++ b/tests/ffi/enable_ffi_test.dart
@@ -4,17 +4,17 @@
 //
 // Dart test program for testing the --enable-ffi=false flag.
 //
+// Note: In AoT and Android the flag is passed to Dart when executing the
+// precompiled executable, so the error shows up as a runtime error rather than
+// a compile time error.
+//
 // VMOptions=--enable-ffi=false
 
-library FfiTest;
-
-import 'dart:ffi' as ffi; //# 01: compile-time error
-
-import "package:expect/expect.dart";
+import 'dart:ffi'; //# 01: compile-time error, runtime error
 
 void main() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate(); //# 01: compile-time error, runtime error
-  p.store(42); //# 01: compile-time error, runtime error
-  Expect.equals(42, p.load<int>()); //# 01: compile-time error, runtime error
+  Pointer<Int8> p = //# 01: compile-time error, runtime error
+      Pointer.allocate(); //# 01: compile-time error, runtime error
+  print(p.address); //# 01: compile-time error, runtime error
   p.free(); //# 01: compile-time error, runtime error
 }
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 9e9b7a4..8902133 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -2,22 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == compare_analyzer_cfe ]
-const_native_factory_test: Fail # Issue 29763
-deferred_global_test: Fail # Issue 34503
-generic_field_mixin2_test: Fail # Issue 34489
-generic_local_functions_test: Fail # Issue 28515
-generic_methods_generic_function_parameter_test: Fail # Issue 28515
-issue34488_test/01: Fail # Issue 34488
-issue34488_test/02: Fail # Issue 34488
-issue34488_test/03: Fail # Issue 34488
-issue34488_test/04: Fail # Issue 34488
-issue34488_test/05: Fail # Issue 34488
-issue34488_test/06: Fail # Issue 34488
-issue34488_test/none: Fail # Issue 34488
-mixin_class_from_core_library_test: Fail # Issue 34488
-nested_generic_closure_test: Fail # Issue 28515
-
 [ $compiler != dart2analyzer ]
 switch_case_warn_test: Skip # Analyzer only, see language_analyzer2.status
 
@@ -48,11 +32,6 @@
 stacktrace_demangle_ctors_test: SkipByDesign # Names are not scrubbed.
 type_checks_in_factory_method_test: SkipByDesign # Requires checked mode.
 
-[ $fasta ]
-partial_instantiation_static_bounds_check_test/01: MissingCompileTimeError # Issue 34327
-partial_instantiation_static_bounds_check_test/02: MissingCompileTimeError # Issue 34327
-partial_instantiation_static_bounds_check_test/03: MissingCompileTimeError # Issue 34327
-
 [ $compiler != dart2js && $compiler != dartdevc && !$checked ]
 function_type/*: Skip # Needs checked mode.
 
@@ -60,6 +39,5 @@
 built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
 
 [ $hot_reload || $hot_reload_rollback ]
-issue_22780_test/01: Pass, Crash # Issue 29094
-static_closure_identical_test: Pass, Fail # Closure identity
+issue_22780_test/01: Crash # Issue 29094
 vm/optimized_stacktrace_test: Slow
diff --git a/tests/language_2/vm/allocate_overflow_array_test.dart b/tests/language_2/vm/allocate_overflow_array_test.dart
new file mode 100644
index 0000000..39d00d3
--- /dev/null
+++ b/tests/language_2/vm/allocate_overflow_array_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+const interestingLengths = <int>[
+  0x3FFFFFFF00000000,
+  0x3FFFFFFFFFFFF000,
+  0x3FFFFFFFFFFFFF00,
+  0x3FFFFFFFFFFFFFF0,
+  0x3FFFFFFFFFFFFFFE,
+  0x3FFFFFFFFFFFFFFF,
+  0x7FFFFFFF00000000,
+  0x7FFFFFFFFFFFF000,
+  0x7FFFFFFFFFFFFF00,
+  0x7FFFFFFFFFFFFFF0,
+  0x7FFFFFFFFFFFFFFE,
+  0x7FFFFFFFFFFFFFFF,
+];
+
+main() {
+  for (int interestingLength in interestingLengths) {
+    for (int elementLength in <int>[1, 2, 3, 4, 5, 6, 7, 8, 9]) {
+      print(interestingLength ~/ elementLength);
+
+      Expect.throws(() {
+        var array = new List(interestingLength ~/ elementLength);
+        print(array.first);
+      }, (e) => e is OutOfMemoryError);
+    }
+  }
+}
diff --git a/tests/language_2/vm/allocate_overflow_bytearray_test.dart b/tests/language_2/vm/allocate_overflow_bytearray_test.dart
new file mode 100644
index 0000000..9242494
--- /dev/null
+++ b/tests/language_2/vm/allocate_overflow_bytearray_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:expect/expect.dart';
+
+const interestingLengths = <int>[
+  0x3FFFFFFF00000000,
+  0x3FFFFFFFFFFFFFF0,
+  0x3FFFFFFFFFFFFFFE,
+  0x3FFFFFFFFFFFFFFF,
+  0x7FFFFFFF00000000,
+  0x7FFFFFFFFFFFFFF0,
+  0x7FFFFFFFFFFFFFFE,
+  0x7FFFFFFFFFFFFFFF,
+];
+
+main() {
+  for (int interestingLength in interestingLengths) {
+    print(interestingLength);
+
+    Expect.throws(() {
+      var bytearray = new Uint8List(interestingLength);
+      print(bytearray.first);
+    }, (e) => e is OutOfMemoryError);
+
+    Expect.throws(() {
+      var bytearray = new Uint8ClampedList(interestingLength);
+      print(bytearray.first);
+    }, (e) => e is OutOfMemoryError);
+
+    Expect.throws(() {
+      var bytearray = new Int8List(interestingLength);
+      print(bytearray.first);
+    }, (e) => e is OutOfMemoryError);
+
+    Expect.throws(() {
+      var bytearray = new ByteData(interestingLength);
+      print(bytearray.getUint8(0));
+    }, (e) => e is OutOfMemoryError);
+  }
+}
diff --git a/tests/language_2/vm/allocate_overflow_string_test.dart b/tests/language_2/vm/allocate_overflow_string_test.dart
new file mode 100644
index 0000000..f4488a1
--- /dev/null
+++ b/tests/language_2/vm/allocate_overflow_string_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+const interestingLengths = <int>[
+  0x3FFFFFFF00000000,
+  0x3FFFFFFFFFFFFFF0,
+  0x3FFFFFFFFFFFFFFE,
+  0x3FFFFFFFFFFFFFFF,
+  0x7FFFFFFF00000000,
+  0x7FFFFFFFFFFFFFF0,
+  0x7FFFFFFFFFFFFFFE,
+  0x7FFFFFFFFFFFFFFF,
+];
+
+main() {
+  for (int interestingLength in interestingLengths) {
+    print(interestingLength);
+
+    Expect.throws(() {
+      var oneByteString = "v";
+      oneByteString *= interestingLength;
+    }, (e) => e is OutOfMemoryError);
+
+    Expect.throws(() {
+      var oneByteString = "v";
+      oneByteString = oneByteString.padLeft(interestingLength);
+    }, (e) => e is OutOfMemoryError);
+
+    Expect.throws(() {
+      var oneByteString = "v";
+      oneByteString = oneByteString.padRight(interestingLength);
+    }, (e) => e is OutOfMemoryError);
+  }
+}
diff --git a/tests/language_2/vm/regression_38412.dart b/tests/language_2/vm/regression_38412.dart
new file mode 100644
index 0000000..b904f05
--- /dev/null
+++ b/tests/language_2/vm/regression_38412.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization_counter_threshold=1
+
+// Found by DartFuzzing: would sometimes fail:
+// https://github.com/dart-lang/sdk/issues/38412
+
+import "package:expect/expect.dart";
+
+import 'dart:async';
+import 'dart:convert';
+
+int fuzzvar1 = -9223372028264841217;
+Map<int, String> fuzzvar8 = {1: "a"};
+
+class X1 {
+  List<int> foo1_0(List<int> par1, String par3) {
+    Expect.equals("not", par3);
+    Expect.equals(10, par1.length);
+    return [1];
+  }
+}
+
+String bar(Map<int, String> o1, int o2) {
+  Expect.equals(1, o1.length);
+  Expect.equals(-9223372028264841218, o2);
+  return "not";
+}
+
+main() {
+  for (int loc0 = 0; loc0 < 7500; loc0++) {
+    "a" == Uri.parse("\u2665");
+  }
+  print('fuzzvar8 runtime type: ${fuzzvar8.runtimeType}');
+  var x =
+      X1().foo1_0([for (int i = 0; i < 10; ++i) 0], bar(fuzzvar8, --fuzzvar1));
+  Expect.equals(1, x[0]);
+}
diff --git a/tests/legacy_status_dart2js.csv b/tests/legacy_status_dart2js.csv
index 5736318..903bfb6 100644
--- a/tests/legacy_status_dart2js.csv
+++ b/tests/legacy_status_dart2js.csv
@@ -409,3 +409,49 @@
 $compiler == dart2js && $minified,html/webgl_1_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
 $compiler == dart2js && ($runtime == ff || $runtime == safari || $ie),html/custom/attribute_changed_callback_test/unsupported_on_polyfill,Fail,Polyfill does not support,,
 $compiler == dart2js && ($runtime == ff || $runtime == safari || $ie),html/custom/entered_left_view_test/viewless_document,Fail,Polyfill does not handle this,,
+$compiler == dart2js,bigint_from_test,RuntimeError,Issue 32589,https://dartbug.com/32589,closed

+$compiler == dart2js,bit_twiddling_test/int64,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,compare_to2_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,core_runtime_types_test,RuntimeError,Issue 34147,https://dartbug.com/34147,open

+$compiler == dart2js,date_time11_test,"RuntimeError, Pass","Fails when US is on winter time, issue 31285.",https://dartbug.com/31285,closed

+$compiler == dart2js,double_ceil_test/int64,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,double_floor_test/int64,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,double_round_test/int64,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,double_truncate_test/int64,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,error_stack_trace1_test,RuntimeError,Issue 12399,https://dartbug.com/12399,closed

+$compiler == dart2js,int_from_environment_int64_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,int_parse_radix_int64_test/01,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,int_parse_radix_int64_test/02,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,int_parse_radix_int64_test/none,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,integer_arith_vm_test/modPow,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,integer_arith_vm_test/none,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,integer_to_string_test/01,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed

+$compiler == dart2js,iterable_return_type_test/02,RuntimeError,Dart2js does not support Uint64*.,,

+$compiler == dart2js,list_unmodifiable_test,"Pass, RuntimeError",Issue 28712,https://dartbug.com/28712,closed

+$compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $runtime != none,map_keys2_test,RuntimeError,needs Dart 2 is checks,,

+$compiler == dart2js && $runtime == chromeOnAndroid,string_trimlr_test/unicode63,RuntimeError,Uses Unicode 6.2.0 or earlier.,,

+$compiler == dart2js && $runtime == d8,uri_base_test,RuntimeError,D8 uses a custom uri scheme for Uri.base,,

+$compiler == dart2js && !$browser,package_resource_test,RuntimeError,Issue 26842,https://dartbug.com/26842,closed

+$compiler == dart2js && $checked,error_stack_trace1_test,RuntimeError,Issue 12399,https://dartbug.com/12399,closed

+$compiler == dart2js && $checked,iterable_return_type_test/01,RuntimeError,Issue 20085,https://dartbug.com/20085,closed

+$compiler == dart2js && $checked,iterable_return_type_test/02,RuntimeError,Dart2js does not support Uint64*.,,

+$compiler == dart2js && $checked,list_replace_range_test,RuntimeError,Issue 32010,https://dartbug.com/32010,open

+$compiler == dart2js && $checked,symbol_reserved_word_test/03,RuntimeError,"Issue 19972, new Symbol('void') should be allowed.",https://dartbug.com/19972,closed

+$compiler == dart2js && $minified,error_stack_trace1_test,RuntimeError,Issue 12399,https://dartbug.com/12399,closed

+$compiler == dart2js && $minified,iterable_return_type_test/02,RuntimeError,Dart2js does not support Uint64*.,,

+$compiler == dart2js && $minified,list_concurrent_modify_test,RuntimeError,dart2js does not fully implement these,,

+$compiler == dart2js && $minified,nsm_invocation_test,RuntimeError,Symbols don't match due to minifiaction.,,

+$compiler == dart2js && $minified,symbol_reserved_word_test/03,RuntimeError,"Issue 19972, new Symbol('void') should be allowed.",https://dartbug.com/19972,closed

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),bit_twiddling_test/int64,"RuntimeError, OK",Requires fixed-size int64 support.,,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),compare_to2_test,"RuntimeError, OK",Requires fixed-size int64 support.,,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),double_ceil_test/int64,"RuntimeError, OK",Requires fixed-size int64 support.,,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),double_floor_test/int64,"RuntimeError, OK",Requires fixed-size int64 support.,,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),double_round_test/int64,"RuntimeError, OK",Requires fixed-size int64 support.,,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),double_truncate_test/int64,"RuntimeError, OK",Requires fixed-size int64 support.,,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),hash_set_test/01,RuntimeError,non JS number semantics - Issue 11551,https://dartbug.com/11551,open

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),int_modulo_arith_test/modPow,RuntimeError,Issue 29921,https://dartbug.com/29921,closed

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),integer_arith_vm_test/modPow,RuntimeError,"Issues 10245, 30170",,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),integer_parsed_arith_vm_test,RuntimeError,"Issues 10245, 29921",,

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),integer_parsed_div_rem_vm_test,RuntimeError,Issue 29921,https://dartbug.com/29921,closed

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),integer_parsed_mul_div_vm_test,RuntimeError,Issue 29921,https://dartbug.com/29921,closed

+$runtime != none && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk),regress_r21715_test,RuntimeError,Requires fixed-size int64 support.,,
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 8aadd79..cde9329 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -14,104 +14,32 @@
 developer/timeline_test: Skip # Not supported
 isolate/issue_24243_parent_isolate_test: Skip # Requires checked mode
 
-[ $runtime == chrome ]
-html/element_animate_test/timing_dict: RuntimeError # Issue 26730
-
 [ $runtime == ff ]
-convert/streamed_conversion_utf8_decode_test: Pass, Slow # Issue 12029
-mirrors/mirrors_reader_test: Timeout, Slow, RuntimeError # Issue 16589
+convert/streamed_conversion_utf8_decode_test: Slow # Issue 12029
+mirrors/mirrors_reader_test: Slow # Issue 16589
 
 [ $runtime == ie11 ]
-html/canvasrenderingcontext2d_test/arc: Pass, Fail # Pixel unexpected value. Please triage this failure.
-html/canvasrenderingcontext2d_test/drawImage_video_element: Fail # IE does not support drawImage w/ video element
-html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # IE does not support drawImage w/ video element
-html/custom/document_register_type_extensions_test/single-parameter: Fail # Issue 13193.
-html/element_animate_test: Fail # Element.animate not supported on these browsers.
-html/element_test/click: Fail # IE does not support firing this event.
-html/event_test: RuntimeError # Issue 23437. Only three failures, but hard to break them out.
-html/gamepad_test: Fail # IE does not support Navigator.getGamepads()
-html/indexeddb_5_test: Fail # Issue 12893
-html/js_transferrables_test: RuntimeError # Issue 14246
-html/js_util_test/callConstructor: RuntimeError # Issue 26978
-html/localstorage_test: Pass, RuntimeError # Issue 22166
-html/mediasource_test: Pass, Fail # Windows 8: Supported: yes, functional: no
-html/notification_test: Fail # Notification not supported on IE
-html/postmessage_structured_test: Fail # Does not support the MessageEvent constructor.
 html/request_animation_frame_test: Skip # Times out. Issue 22167
-html/storage_test: Pass, RuntimeError # Issue 22166
-html/text_event_test: RuntimeError # Issue 23437
-html/touchevent_test: Fail # IE does not support TouchEvents
-html/transferables_test: Pass, Fail # Issues 20659.
 html/transition_event_test: Skip # Times out. Issue 22167
-html/websocket_test: Fail # Issue 7875. Closed with "working as intended".
-html/wheelevent_test: RuntimeError # Issue 23437
-html/worker_test/functional: Pass, Fail # Issues 20659.
-html/xhr_test/json: Fail # IE10 returns string, not JSON object
 
 [ $runtime == safari ]
-html/canvasrenderingcontext2d_test/drawImage_video_element: Fail # Safari does not support drawImage w/ video element
-html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # Safari does not support drawImage w/ video element
-html/element_animate_test: Fail # Element.animate not supported on these browsers.
-html/element_test: Pass, Fail # Issue 21434
-html/gamepad_test: Fail # Safari does not support Navigator.getGamepads()
 html/indexeddb_1_test/functional: Skip # Times out. Issue 21433
-html/indexeddb_2_test: RuntimeError # Issue 21433
 html/indexeddb_3_test: Skip # Times out 1 out of 10.
-html/indexeddb_4_test: RuntimeError # Issue 21433
-html/indexeddb_5_test: RuntimeError # Issue 21433
-html/mediasource_test: Pass, Fail # MediaSource only available on Safari 8 desktop, we can't express that.
-html/webgl_1_test: Pass, Fail # Issue 8219
 html/worker_api_test: Skip # Issue 13221
-typed_data/float32x4_test: Fail, Pass # Safari has an optimization bug (nightlies are already fine).
-typed_data/int32x4_test: Fail, Pass # Safari has an optimization bug (nightlies are already fine).
 
 [ $system == windows ]
 html/xhr_test/xhr: Skip # Times out.  Issue 21527
 
-[ $browser ]
-async/periodic_timer2_test: Pass, RuntimeError # Flaky. Issue 32094
-async/periodic_timer3_test: Pass, RuntimeError # Flaky. Issue 32094
-async/periodic_timer4_test: Pass, RuntimeError # Flaky. Issue 32094
-
 [ $csp ]
 isolate/deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode
 
-[ $hot_reload ]
-async/stream_periodic4_test: Pass, RuntimeError # Issue 30904
-mirrors/dynamic_load_test: RuntimeError # Issue 26869 - Reload fails to preserve library identity
-
-[ $jscl ]
-isolate/spawn_uri_multi_test/none: RuntimeError # Issue 13544
-
-[ $builder_tag == mac10_7 && $runtime == safari ]
-typed_data/setRange_2_test: Fail # Safari doesn't fully implement spec for TypedArray.set
-typed_data/setRange_3_test: Fail # Safari doesn't fully implement spec for TypedArray.set
-typed_data/setRange_4_test: Fail # Safari doesn't fully implement spec for TypedArray.set
-
-[ $compiler == dartk && $system == macos && $hot_reload && ($arch == simdbc || $arch == simdbc64) ]
-isolate/unresolved_ports_test: Pass, RuntimeError #  Issue 35410
-
-[ $compiler == none && $mode == product ]
-mirrors/library_enumeration_deferred_loading_test: RuntimeError, OK # Deferred loaded eagerly
-mirrors/library_import_deferred_loading_test: RuntimeError, OK # Deferred loaded eagerly
-mirrors/load_library_test: RuntimeError, OK # Deferred loaded eagerly
-
-[ $compiler == none && !$checked ]
-mirrors/reflected_type_generics_test/02: Fail, OK # Type check for a bounded type argument.
-
 [ $runtime == chrome && $system == linux ]
 mirrors/native_class_test: Slow
 
 [ $runtime == chrome && $system == macos ]
-async/catch_errors11_test: Pass, Timeout # Issue 22696
-async/slow_consumer_test: Pass, Timeout # Issue 22696
-async/timer_isActive_test: Fail, Pass, Timeout # Issue 22696
 convert/streamed_conversion_utf8_encode_test: SkipSlow # Times out. Issue 22050
 html/canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
 html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Skip # Times out. Please triage this failure.
-html/custom_element_method_clash_test: Pass, Timeout # Issue 26789
-html/custom_element_name_clash_test: Pass, Timeout # Issue 26789
-html/custom_elements_test: Pass, Timeout # Issue 26789
 html/request_animation_frame_test: Skip # Times out. Issue 22167
 html/transition_event_test: Skip # Times out. Issue 22167
 
@@ -134,16 +62,12 @@
 [ $mode == product || $runtime != vm ]
 isolate/checked_test: Skip # Unsupported.
 
-[ $runtime == chrome || $runtime == chromeOnAndroid ]
-html/webgl_1_test: Pass, Fail # Issue 8219
-
 [ $runtime == chrome || $runtime == ff ]
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
 async/stream_timeout_test: SkipSlow # Times out. Issue 22050
 
 [ $runtime == dart_precompiled || $runtime == vm ]
 isolate/isolate_stress_test: Skip # Issue 12588: Uses dart:html. This should be able to pass when we have wrapper-less tests.
-isolate/stacktrace_message_test: RuntimeError # Fails to send stacktrace object.
 
 # It makes no sense to run any test that uses spawnURI under the simulator
 # as that would involve running CFE (the front end) in simulator mode
@@ -186,15 +110,12 @@
 isolate/unresolved_ports_test: Skip # Isolate.spawnUri
 
 [ $hot_reload || $hot_reload_rollback ]
-async/stream_transformer_test: Pass, Fail # Closure identity
 convert/chunked_conversion_utf88_test: SkipSlow
 convert/utf85_test: SkipSlow
 isolate/deferred_in_isolate2_test: Crash # Requires deferred libraries
 isolate/deferred_in_isolate_test: Crash # Requires deferred libraries
-isolate/function_send_test: Pass, Fail # Closure identity
 isolate/issue_21398_parent_isolate2_test: Crash # Requires deferred libraries
-isolate/message3_test/fun: Pass, Fail # Closure identity
-isolate/spawn_uri_nested_vm_test: Pass, Crash # Issue 28192
+isolate/spawn_uri_nested_vm_test: Crash # Issue 28192
 mirrors/closurization_equivalence_test: SkipByDesign # Method equality
 mirrors/deferred_constraints_constants_test: Crash # Requires deferred libraries
 mirrors/deferred_mirrors_metadata_test: Crash # Deferred loading
diff --git a/tests/lib_2/wasm/basic_test.dart b/tests/lib_2/wasm/basic_test.dart
index 4ab1e7c..b6dfaa9 100644
--- a/tests/lib_2/wasm/basic_test.dart
+++ b/tests/lib_2/wasm/basic_test.dart
@@ -20,9 +20,7 @@
     0x7e, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports()
-    ..addMemory("env", "memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports());
   var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
   int n = fn.call([1234]);
 
diff --git a/tests/lib_2/wasm/fn_call_error_test.dart b/tests/lib_2/wasm/fn_call_error_test.dart
index db696d7..932afa3 100644
--- a/tests/lib_2/wasm/fn_call_error_test.dart
+++ b/tests/lib_2/wasm/fn_call_error_test.dart
@@ -20,9 +20,7 @@
     0x7e, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports()
-    ..addMemory("env", "memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports());
   var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
 
   Expect.throwsArgumentError(() => fn.call([]));
diff --git a/tests/lib_2/wasm/fn_import_test.dart b/tests/lib_2/wasm/fn_import_test.dart
index 8172c20..a9f9bdb 100644
--- a/tests/lib_2/wasm/fn_import_test.dart
+++ b/tests/lib_2/wasm/fn_import_test.dart
@@ -26,8 +26,6 @@
   int report_y = -1;
 
   var inst = WasmModule(data).instantiate(WasmImports()
-    ..addMemory("env", "memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("env", "__memory_base", 1024, false)
     ..addFunction<Void Function(Int64, Int64)>("env", "report", (int x, int y) {
       report_x = x;
       report_y = y;
diff --git a/tests/lib_2/wasm/fn_mismatch_error_test.dart b/tests/lib_2/wasm/fn_mismatch_error_test.dart
index 01e825b..413260e 100644
--- a/tests/lib_2/wasm/fn_mismatch_error_test.dart
+++ b/tests/lib_2/wasm/fn_mismatch_error_test.dart
@@ -20,9 +20,7 @@
     0x7e, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports()
-    ..addMemory("env", "memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports());
   Expect.isNotNull(inst.lookupFunction<Int64 Function(Int64)>("square"));
   Expect.throwsArgumentError(
       () => inst.lookupFunction<Int64 Function(Int64)>("blah"));
diff --git a/tests/lib_2/wasm/hello_world_test.dart b/tests/lib_2/wasm/hello_world_test.dart
new file mode 100644
index 0000000..c4441e3
--- /dev/null
+++ b/tests/lib_2/wasm/hello_world_test.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for hello world built using emscripten with WASI.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+  // Hello world module generated by emscripten+WASI. Exports a function like
+  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
+  var data = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
+    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
+    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
+    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
+    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
+    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
+    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
+    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
+    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
+    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
+    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
+    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
+    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
+    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
+    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
+    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
+    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
+    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
+    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
+    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
+    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
+    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
+    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
+    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
+    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
+    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
+    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
+    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
+    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
+    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
+    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
+    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
+    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
+    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
+    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
+    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
+    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
+    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
+    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
+    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
+    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
+    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
+    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
+    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
+    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
+    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
+    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
+    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
+    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
+    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
+    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
+    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
+    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
+    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
+    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
+    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
+    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
+    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
+    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
+    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
+    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
+    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
+    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
+    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
+    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
+    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
+    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
+    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
+    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
+    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
+    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
+    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
+    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
+    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
+    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
+    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
+    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
+    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
+    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
+    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
+    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
+    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
+    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
+    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
+    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
+    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
+    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
+    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
+    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
+    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
+    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
+    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
+    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
+    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
+    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
+    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
+    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
+    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
+    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
+    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
+    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
+    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
+    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
+    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
+    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
+    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
+    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
+    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
+    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
+    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
+    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
+    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
+    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
+    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
+    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
+    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
+    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
+    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
+    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
+    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
+    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
+    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
+    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
+  ]);
+
+  WasmMemory mem = null;
+  String out = "";
+  var getI32 = (int p) {
+    // Read a little-endian I32.
+    int n = 0;
+    for (var i = p + 3; i >= p; --i) {
+      n *= 256;
+      n += mem[i];
+    }
+    return n;
+  };
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addFunction<Int32 Function(Int32, Int32, Int32, Int32)>(
+        "wasi_unstable", "fd_write",
+        (int fd, int iovs, int iovs_len, int unused) {
+      // iovs points to an array of length iovs_len. Each element is two I32s,
+      // a char* and a length.
+      String o = "";
+      for (var i = 0; i < iovs_len; ++i) {
+        var str = getI32(iovs + 8 * i);
+        var len = getI32(iovs + 4 + 8 * i);
+        for (var j = 0; j < len; ++j) {
+          o += String.fromCharCode(mem[str + j]);
+        }
+      }
+      out += o;
+      return o.length;
+    }));
+  mem = inst.memory;
+
+  var fn = inst.lookupFunction<Void Function()>("_start");
+  fn.call([]);
+  Expect.equals("hello, world!\n", out);
+}
diff --git a/tests/lib_2/wasm/import_error_test.dart b/tests/lib_2/wasm/import_error_test.dart
index 071dc4b..a06a3a9 100644
--- a/tests/lib_2/wasm/import_error_test.dart
+++ b/tests/lib_2/wasm/import_error_test.dart
@@ -10,6 +10,8 @@
 
 void main() {
   var imp = WasmImports();
+  imp.addGlobal<Int64>("env", "x", 123, false);
+  imp.addGlobal<Double>("env", "y", 4.56, true);
   Expect.throwsArgumentError(() => imp.addGlobal<int>("env", "a", 1, true));
   Expect.throwsArgumentError(() => imp.addGlobal<double>("env", "b", 2, true));
   Expect.throwsArgumentError(() => imp.addGlobal<dynamic>("env", "c", 3, true));
diff --git a/tests/lib_2/wasm/numerics_test.dart b/tests/lib_2/wasm/numerics_test.dart
index 6255d20..8651caa 100644
--- a/tests/lib_2/wasm/numerics_test.dart
+++ b/tests/lib_2/wasm/numerics_test.dart
@@ -29,9 +29,7 @@
     0x01, 0x92, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports()
-    ..addMemory("env", "memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports());
   var addI64 = inst.lookupFunction<Int64 Function(Int64, Int64)>("addI64");
   var addI32 = inst.lookupFunction<Int32 Function(Int32, Int32)>("addI32");
   var addF64 = inst.lookupFunction<Double Function(Double, Double)>("addF64");
diff --git a/tests/lib_2/wasm/void_test.dart b/tests/lib_2/wasm/void_test.dart
index 210c9b0..fe3bd94 100644
--- a/tests/lib_2/wasm/void_test.dart
+++ b/tests/lib_2/wasm/void_test.dart
@@ -25,9 +25,7 @@
     0x80, 0x08, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports()
-    ..addMemory("env", "memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports());
   var setFn = inst.lookupFunction<Void Function(Int64, Int64)>("set");
   var getFn = inst.lookupFunction<Int64 Function()>("get");
   Expect.isNull(setFn.call([123, 456]));
diff --git a/tests/modular/diamond/a.dart b/tests/modular/diamond/a.dart
new file mode 100644
index 0000000..63956ec
--- /dev/null
+++ b/tests/modular/diamond/a.dart
@@ -0,0 +1,3 @@
+import 'b.dart';
+
+var item = b;
diff --git a/tests/modular/diamond/b.dart b/tests/modular/diamond/b.dart
new file mode 100644
index 0000000..07a55aa
--- /dev/null
+++ b/tests/modular/diamond/b.dart
@@ -0,0 +1,3 @@
+class B {}
+
+var b = new B();
diff --git a/tests/modular/diamond/main.dart b/tests/modular/diamond/main.dart
new file mode 100644
index 0000000..a112564
--- /dev/null
+++ b/tests/modular/diamond/main.dart
@@ -0,0 +1,6 @@
+import 'b.dart';
+import 'a.dart';
+
+main() {
+  print([item, b]);
+}
diff --git a/tests/modular/diamond/modules.yaml b/tests/modular/diamond/modules.yaml
new file mode 100644
index 0000000..2fd373c
--- /dev/null
+++ b/tests/modular/diamond/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+  main: [a, b]
+  a: b
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index 7f28264..066fe56 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -9,17 +9,6 @@
 io/non_utf8_directory_test: Skip # Issue 33519. Temp files causing bots to go purple.
 io/non_utf8_file_test: Skip # Issue 33519. Temp files causing bots to go purple.
 io/non_utf8_link_test: Skip # Issue 33519. Temp files causing bots to go purple.
-io/raw_socket_test: Pass, RuntimeError # Issue 28288
-issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
-package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
-package/package1_test: Fail # imports 'package:foo.dart' which is no longer valid
-package/package_test: Fail # imports 'package:foo.dart' which is no longer valid
-package/scenarios/empty_packages_file/empty_packages_file_discovery_test: Fail, OK # CompileTimeErrors intentionally
-package/scenarios/empty_packages_file/empty_packages_file_option_test: Fail, OK # CompileTimeErrors intentionally
-package/scenarios/invalid/invalid_package_name_test: RuntimeError, CompileTimeError # Errors intentionally
-package/scenarios/invalid/same_package_twice_test.dart: RuntimeError, CompileTimeError # Errors intentionally
-package/scenarios/packages_dir_only/packages_dir_only_test: Fail # Confirm this no longer works for now. TODO(mfairhurst): delete this test.
-package/scenarios/packages_file_strange_formatting/empty_package_dir_test: Fail, OK # CompileTimeErrors intentionally
 packages_file_test: Skip # Issue 26715
 packages_file_test/none: Skip # contains no tests.
 
@@ -75,23 +64,18 @@
 
 [ $compiler != none && $runtime != dart_precompiled && $runtime != vm ]
 env_test: Skip # This is testing a vm command line parsing scenario.
-no_assert_test: Fail, OK # This is testing a vm flag.
 
 [ $mode == product && $runtime == dart_precompiled ]
 dwarf_stack_trace_test: SkipByDesign # Due to instruction canonicalization we can end up having the wrong names in stack traces.
 
-[ $mode == release && $runtime == vm && $system == macos ]
-io/named_pipe_script_test: Pass, RuntimeError # Issue 28737
-
 [ $runtime == vm && $system == linux ]
-io/http_basic_test: Pass, Slow, Timeout # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
-io/http_launch_test: Pass, Slow, Timeout # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
+io/http_basic_test: Slow # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
+io/http_launch_test: Slow # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
 
 [ $system == macos && ($runtime == dart_precompiled || $runtime == vm) ]
-io/raw_secure_server_socket_test: Pass, Crash # Issue 29524
+io/raw_secure_server_socket_test: Crash
 io/raw_server_socket_cancel_test: Skip # Issue 28182 # This test sometimes hangs on Mac.
 io/secure_server_client_certificate_test: Skip # Re-enable once the bots have been updated. Issue #26057
-io/socket_connect_stream_data_close_cancel_test: Pass, Timeout # Issue 27453
 io/socket_many_connections_test: Skip # This test fails with "Too many open files" on the Mac OS buildbot. This is expected as MacOS by default runs with a very low number of allowed open files ('ulimit -n' says something like 256).
 
 [ $arch == arm || $arch == arm64 || $runtime != vm || $mode == debug && $system == windows ]
@@ -105,17 +89,11 @@
 
 [ $runtime == dart_precompiled || $runtime == vm ]
 deferred_transitive_import_error_test: Skip
-io/https_client_certificate_test: RuntimeError # Issue 24070 Failures in secure networking while NSS is replaced with BoringSSL
-io/non_utf8_output_test: NonUtf8Output, OK # This test checks that the test runner correctly detects and reports non-utf8 output from a test.
-io/secure_socket_bad_data_test: RuntimeError # An error in a secure connection just puts a READ_CLOSED on the stream, rather than signaling an error on the stream.
-package/package_isolate_test: Fail # Issue 12474
-package/scenarios/invalid/same_package_twice_test: Pass # Issue 24119
 
 [ $hot_reload || $hot_reload_rollback ]
-fragmentation_test: Pass, Crash # Issue 31421
-io/addlatexhash_test: Pass, Crash # Issue 31252
+fragmentation_test: Crash # Issue 31421
+io/addlatexhash_test: Crash # Issue 31252
 io/many_directory_operations_test: SkipSlow
 io/many_file_operations_test: SkipSlow
-io/raw_datagram_read_all_test: Pass, Fail # Timing dependent.
 package/*: SkipByDesign # Launches VMs in interesting ways.
 typed_data_isolate_test: SkipSlow
diff --git a/tools/VERSION b/tools/VERSION
index f4e2a13..72b118c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 6
 PATCH 0
-PRERELEASE 4
+PRERELEASE 5
 PRERELEASE_PATCH 0
 ABI_VERSION 16
 OLDEST_SUPPORTED_ABI_VERSION 16
diff --git a/tools/bots/aot_smoke_tests.dart b/tools/bots/aot_smoke_tests.dart
index a035361..fba0c9d 100755
--- a/tools/bots/aot_smoke_tests.dart
+++ b/tools/bots/aot_smoke_tests.dart
@@ -38,7 +38,7 @@
   test("dart2aot: Can compile and run AOT", () async {
     await withTempDir((String tmp) async {
       final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
-      final String tmpAot = path.join(tmp, 'dart_aot_test.dart.aot');
+      final String tmpAot = path.join(tmp, 'dart_aot_test.aot');
 
       {
         final ProcessResult result =
@@ -62,7 +62,7 @@
   test("dart2native: Can compile and run AOT", () async {
     await withTempDir((String tmp) async {
       final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
-      final String tmpAot = path.join(tmp, 'dart_aot_test.dart.aot');
+      final String tmpAot = path.join(tmp, 'dart_aot_test.aot');
 
       {
         final ProcessResult result = await Process.run(dart2native,
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index e371239..4f7b4c5 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -45,7 +45,9 @@
     on several different runtimes.
   - builder_tag: A tag indicating a special builder setup.
   - cps_ir: Run the compiler with the cps based backend
+  - use_nnbd: Whether to use the NNBD fork of the SDK.
   """
+    # TODO: Remove use_nnbd when the fork is merged back in.
 
     def __init__(self,
                  compiler,
@@ -64,7 +66,8 @@
                  dart2js_full=False,
                  builder_tag=None,
                  batch=False,
-                 cps_ir=False):
+                 cps_ir=False,
+                 use_nnbd=False):
         self.compiler = compiler
         self.runtime = runtime
         self.mode = mode
@@ -81,6 +84,7 @@
         self.builder_tag = builder_tag
         self.batch = batch
         self.cps_ir = cps_ir
+        self.use_nnbd = use_nnbd
         if (arch == None):
             self.arch = 'ia32'
         else:
@@ -268,11 +272,20 @@
     """
   Runs the test package's runner on the package at 'path'.
   """
+    # TODO(38701): Once bots are set up to run NNBD configurations, update
+    # the various name parsing functions to detect that and pass "use_nnbd" to
+    # the BuildInfo() constructor.
+
     sdk_bin = os.path.join(
         bot_utils.DART_DIR,
-        utils.GetBuildSdkBin(BUILD_OS, build_info.mode, build_info.arch))
+        utils.GetBuildSdkBin(BUILD_OS, build_info.mode, build_info.arch,
+                             build_info.use_nnbd))
 
-    build_root = utils.GetBuildRoot(BUILD_OS, build_info.mode, build_info.arch)
+    build_root = utils.GetBuildRoot(
+        BUILD_OS,
+        build_info.mode,
+        build_info.arch,
+        use_nnbd=build_info.use_nnbd)
 
     dart_name = 'dart.exe' if build_info.system == 'windows' else 'dart'
     dart_bin = os.path.join(sdk_bin, dart_name)
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 201302b..1cc16e0 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -227,6 +227,7 @@
       "pkg/async_helper/",
       "pkg/build_integration/",
       "pkg/dart_internal/",
+      "pkg/dart2native/",
       "pkg/expect/",
       "pkg/front_end/",
       "pkg/js/",
diff --git a/tools/build.py b/tools/build.py
index 904c6560..6eef99c 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -63,6 +63,13 @@
         help='Target OSs (comma-separated).',
         metavar='[all,host,android]',
         default='host')
+    # TODO(38701): Remove this and everything that references it once the
+    # forked NNBD SDK is merged back in.
+    result.add_option(
+        "--nnbd",
+        help='Use the NNBD fork of the SDK.',
+        default=False,
+        action='store_true')
     result.add_option(
         "-v",
         "--verbose",
@@ -200,7 +207,7 @@
     return True
 
 
-def RunGNIfNeeded(out_dir, target_os, mode, arch):
+def RunGNIfNeeded(out_dir, target_os, mode, arch, use_nnbd):
     if os.path.isfile(os.path.join(out_dir, 'args.gn')):
         return
     gn_os = 'host' if target_os == HOST_OS else target_os
@@ -215,6 +222,9 @@
         gn_os,
         '-v',
     ]
+    if use_nnbd:
+        gn_command.append('--nnbd')
+
     process = subprocess.Popen(gn_command)
     process.wait()
     if process.returncode != 0:
@@ -268,12 +278,12 @@
 
 # Returns a tuple (build_config, command to run, whether goma is used)
 def BuildOneConfig(options, targets, target_os, mode, arch):
-    build_config = utils.GetBuildConf(mode, arch, target_os)
-    out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
+    build_config = utils.GetBuildConf(mode, arch, target_os, options.nnbd)
+    out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os, options.nnbd)
     using_goma = False
     # TODO(zra): Remove auto-run of gn, replace with prompt for user to run
     # gn.py manually.
-    RunGNIfNeeded(out_dir, target_os, mode, arch)
+    RunGNIfNeeded(out_dir, target_os, mode, arch, options.nnbd)
     command = ['ninja', '-C', out_dir]
     if options.verbose:
         command += ['-v']
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index dff4c0e..82358dc 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -72,6 +72,7 @@
 
 extension-methods:
   help: "Extension Methods"
+  enabledIn: '2.6.0'
 
 non-nullable:
   help: "Non Nullable by default"
diff --git a/tools/gn.py b/tools/gn.py
index 5cdcc3e..2b023a3 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -66,8 +66,9 @@
     return args.split()
 
 
-def GetOutDir(mode, arch, target_os):
-    return utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
+# TODO(38701): Remove use_nnbd once the forked NNBD SDK is merged back in.
+def GetOutDir(mode, arch, target_os, use_nnbd):
+    return utils.GetBuildRoot(HOST_OS, mode, arch, target_os, use_nnbd)
 
 
 def ToCommandLine(gn_args):
@@ -166,7 +167,8 @@
     return True
 
 
-def ToGnArgs(args, mode, arch, target_os):
+# TODO(38701): Remove use_nnbd once the forked NNBD SDK is merged back in.
+def ToGnArgs(args, mode, arch, target_os, use_nnbd):
     gn_args = {}
 
     host_os = HostOsForGn(HOST_OS)
@@ -284,6 +286,8 @@
         gn_args['dart_debug_optimization_level'] = args.debug_opt_level
         gn_args['debug_optimization_level'] = args.debug_opt_level
 
+    gn_args['use_nnbd'] = use_nnbd
+
     return gn_args
 
 
@@ -385,6 +389,12 @@
         help='Target OSs (comma-separated).',
         metavar='[all,host,android]',
         default='host')
+    # TODO(38701): Remove this once the forked NNBD SDK is merged back in.
+    common_group.add_argument(
+        "--nnbd",
+        help='Use the NNBD fork of the SDK.',
+        default=False,
+        action='store_true')
     common_group.add_argument(
         "-v",
         "--verbose",
@@ -533,12 +543,13 @@
     for target_os in args.os:
         for mode in args.mode:
             for arch in args.arch:
-                out_dir = GetOutDir(mode, arch, target_os)
+                out_dir = GetOutDir(mode, arch, target_os, args.nnbd)
                 # TODO(infra): Re-enable --check. Many targets fail to use
                 # public_deps to re-expose header files to their dependents.
                 # See dartbug.com/32364
                 command = [gn, 'gen', out_dir]
-                gn_args = ToCommandLine(ToGnArgs(args, mode, arch, target_os))
+                gn_args = ToCommandLine(
+                    ToGnArgs(args, mode, arch, target_os, args.nnbd))
                 gn_args += GetGNArgs(args)
                 if args.verbose:
                     print("gn gen --check in %s" % out_dir)
diff --git a/tools/utils.py b/tools/utils.py
index 2eb4289..085236a 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -308,32 +308,42 @@
             (target_os != GuessOS()))
 
 
-def GetBuildConf(mode, arch, conf_os=None):
+# TODO(38701): Remove use_nnbd once the forked NNBD SDK is merged back in.
+def GetBuildConf(mode, arch, conf_os=None, use_nnbd=False):
+    nnbd = "NNBD" if use_nnbd else ""
     if conf_os == 'android':
-        return '%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper())
+        return '%s%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper(),
+                             nnbd)
     else:
         # Ask for a cross build if the host and target architectures don't match.
         host_arch = ARCH_GUESS
         cross_build = ''
         if GetArchFamily(host_arch) != GetArchFamily(arch):
             cross_build = 'X'
-        return '%s%s%s' % (GetBuildMode(mode), cross_build, arch.upper())
+        return '%s%s%s%s' % (GetBuildMode(mode), cross_build, arch.upper(),
+                             nnbd)
 
 
 def GetBuildDir(host_os):
     return BUILD_ROOT[host_os]
 
 
-def GetBuildRoot(host_os, mode=None, arch=None, target_os=None):
+# TODO(38701): Remove use_nnbd once the forked NNBD SDK is merged back in.
+def GetBuildRoot(host_os, mode=None, arch=None, target_os=None, use_nnbd=False):
     build_root = GetBuildDir(host_os)
     if mode:
-        build_root = os.path.join(build_root, GetBuildConf(
-            mode, arch, target_os))
+        build_root = os.path.join(build_root,
+                                  GetBuildConf(mode, arch, target_os, use_nnbd))
     return build_root
 
 
-def GetBuildSdkBin(host_os, mode=None, arch=None, target_os=None):
-    build_root = GetBuildRoot(host_os, mode, arch, target_os)
+# TODO(38701): Remove use_nnbd once the forked NNBD SDK is merged back in.
+def GetBuildSdkBin(host_os,
+                   mode=None,
+                   arch=None,
+                   target_os=None,
+                   use_nnbd=False):
+    build_root = GetBuildRoot(host_os, mode, arch, target_os, use_nnbd)
     return os.path.join(build_root, 'dart-sdk', 'bin')
 
 
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 8662ed1..f80450c 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -269,7 +269,6 @@
       }
     }
 
-    // TODO(sigmund): add support for experiments with the incremental compiler.
     state = await fe.initializeIncrementalCompiler(
         previousState,
         {