Version 2.15.0-91.0.dev

Merge commit 'e9b287a9c106cc0f0f4107af8575cfe08cea8e24' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9371d2d..95f63a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -95,7 +95,11 @@
 
 #### Linter
 
-Updated the Linter to `1.10.0`, which includes changes that
+Updated the Linter to `1.11.0`, which includes changes that
+- adds support for constructor tear-offs to `avoid_redundant_argument_values`, 
+  `unnecessary_lambdas`, and `unnecessary_parenthesis`.
+- adds a new lint: `unnecessary_constructor_name` to flag unnecessary uses of 
+  `.new`.
 - improves regular expression parsing performance for common checks
   (`camel_case_types`, `file_names`, etc.).
 - (internal) migrates to analyzer 2.1.0 APIs.
diff --git a/DEPS b/DEPS
index 0719a0f..728cf56 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
 
   # Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a
   # cipd package used to run Dart scripts in the build and test infrastructure.
-  "sdk_tag": "version:2.14.0-377.4.beta",
+  "sdk_tag": "version:2.15.0-82.0.dev",
 
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
@@ -86,10 +86,10 @@
   "chrome_rev" : "19997",
   "cli_util_rev" : "8c504de5deb08fe32ecf51f9662bb37d8c708e57",
   "clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3",
-  "collection_rev": "75a7a5510979a3cd70143af85bcc1667ee233674",
+  "collection_rev": "a4c941ab94044d118b2086a3f261c30377604127",
   "convert_rev": "e063fdca4bebffecbb5e6aa5525995120982d9ce",
   "crypto_rev": "b5024e4de2b1c474dd558bef593ddbf0bfade152",
-  "csslib_rev": "e411d862fd8cc50415c1badf2632e017373b3f47",
+  "csslib_rev": "6338de25a09d098a62c9a1992c175e9ceb5b994a",
 
   # Note: Updates to dart_style have to be coordinated with the infrastructure
   # team so that the internal formatter in `tools/sdks/dart-sdk/bin/dartfmt`
@@ -105,7 +105,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_rev": "14d9b6fd58cc4744676c12be3cc5eee2a779db82",
 
-  "dartdoc_rev" : "348cbd7204645f99074bf7873af8b6ba6d34ceb0",
+  "dartdoc_rev" : "7fd237db737752800505eff510bf3fa8d3e00eb7",
   "devtools_rev" : "2b47d9ed486479153ca2fd038000950674ed1beb",
   "jsshell_tag": "version:88.0",
   "ffi_rev": "4dd32429880a57b64edaf54c9d5af8a9fa9a4ffb",
@@ -122,7 +122,7 @@
   "intl_tag": "0.17.0-nullsafety",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
-  "linter_tag": "1.10.0",
+  "linter_tag": "1.11.0",
   "lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
   "logging_rev": "575781ef196e4fed4fb737e38fb4b73d62727187",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
@@ -173,7 +173,7 @@
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
   "webdev_rev": "832b096c0c24798d3df46faa7b7661fe930573c2",
   "webkit_inspection_protocol_rev": "dd6fb5d8b536e19cedb384d0bbf1f5631923f1e8",
-  "yaml_rev": "b4c4411631bda556ce9a45af1ab0eecaf9f3ac53",
+  "yaml_rev": "2af44871f684c89e973a96e39026b8b88dda1987",
   "zlib_rev": "bf44340d1b6be1af8950bbdf664fec0cf5a831cc",
   "crashpad_rev": "bf327d8ceb6a669607b0dbab5a83a275d03f99ed",
   "minichromium_rev": "8d641e30a8b12088649606b912c2bc4947419ccc",
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/local_boolean_new.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/local_boolean_new.dart
new file mode 100644
index 0000000..50dba2c
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/nullability/data/local_boolean_new.dart
@@ -0,0 +1,228 @@
+// Copyright (c) 2020, 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.
+
+finalLocalBool(int? x) {
+  final bool b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+finalLocalBool_untyped(int? x) {
+  final b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+localBool(int? x) {
+  bool b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+localBool_untyped(int? x) {
+  var b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+localBool_assigned(int? x, bool b1) {
+  bool b2 = b1;
+  b2 = x == null;
+  if (!b2) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+localBool_assigned_untyped(int? x, bool b1) {
+  var b2 = b1;
+  b2 = x == null;
+  if (!b2) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+localBool_assignedDynamic(int? x, bool b1) {
+  dynamic b2 = b1;
+  b2 = x == null;
+  if (!b2) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+parameter_assigned(int? x, bool b) {
+  b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+parameter_assigned_untyped(int? x, b) {
+  b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+parameter_assignedDynamic(int? x, dynamic b) {
+  b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+lateFinalLocalBool(int? x) {
+  late final bool b = x == null;
+  if (!b) {
+    // We don't promote based on the initializers of late locals because we
+    // don't know when they execute.
+    x;
+  } else {
+    x;
+  }
+}
+
+lateFinalLocalBool_untyped(int? x) {
+  late final b = x == null;
+  if (!b) {
+    // We don't promote based on the initializers of late locals because we
+    // don't know when they execute.
+    x;
+  } else {
+    x;
+  }
+}
+
+lateLocalBool(int? x) {
+  late bool b = x == null;
+  if (!b) {
+    // We don't promote based on the initializers of late locals because we
+    // don't know when they execute.
+    x;
+  } else {
+    x;
+  }
+}
+
+lateLocalBool_untyped(int? x) {
+  late var b = x == null;
+  if (!b) {
+    // We don't promote based on the initializers of late locals because we
+    // don't know when they execute.
+    x;
+  } else {
+    x;
+  }
+}
+
+lateLocalBool_assignedAndInitialized(int? x, bool b1) {
+  late bool b2 = b1;
+  b2 = x == null;
+  if (!b2) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+lateLocalBool_assignedAndInitialized_untyped(int? x, bool b1) {
+  late var b2 = b1;
+  b2 = x == null;
+  if (!b2) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+lateLocalBool_assignedButNotInitialized(int? x) {
+  late bool b;
+  b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+lateLocalBool_assignedButNotInitialized_untyped(int? x) {
+  late var b;
+  b = x == null;
+  if (!b) {
+    /*nonNullable*/ x;
+  } else {
+    x;
+  }
+}
+
+rebaseWithDemotion(int? x, int? y, int? z, int? a) {
+  x;
+  y;
+  z;
+  if (y == null) return;
+  x;
+  /*nonNullable*/ y;
+  z;
+  bool b = x == null;
+  x;
+  /*nonNullable*/ y;
+  z;
+  if (z == null) return;
+  x;
+  /*nonNullable*/ y;
+  /*nonNullable*/ z;
+  y = a;
+  x;
+  y;
+  /*nonNullable*/ z;
+  if (b) return;
+  /*nonNullable*/ x;
+  y;
+  /*nonNullable*/ z;
+}
+
+compoundAssignment(int? x, dynamic b) {
+  b += x == null;
+  if (!b) {
+    // It's not safe to promote, because there's no guarantee that value of `b`
+    // has anything to do with the result of `x == null`.
+    x;
+  } else {
+    x;
+  }
+}
+
+ifNullAssignment(int? x, dynamic b) {
+  b ??= x == null;
+  if (!b) {
+    // It's not safe to promote, because there's no guarantee that value of `b`
+    // has anything to do with the result of `x == null`.
+    x;
+  } else {
+    x;
+  }
+}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index ff410a2..9934b5b 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -4355,7 +4355,7 @@
       </dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
         
         <p>Deprecated - no longer sent.</p>
-      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
+      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_METHOD_TEAR_OFF</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_FUNCTION_TEAR_OFF</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
         
         <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
@@ -4379,7 +4379,7 @@
       </dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
         
         <p>Deprecated - no longer sent.</p>
-      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_ALIAS</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
+      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_METHOD_TEAR_OFF</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_TEAR_OFF</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_ALIAS</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
     <p>
       The hover information associated with a specific location.
     </p>
diff --git a/pkg/analysis_server/doc/tutorial/quick_fix.md b/pkg/analysis_server/doc/tutorial/quick_fix.md
index 3085dd9..dcb1bc6 100644
--- a/pkg/analysis_server/doc/tutorial/quick_fix.md
+++ b/pkg/analysis_server/doc/tutorial/quick_fix.md
@@ -394,7 +394,7 @@
 fixes that might need to be produced. For example, if there is an undefined
 identifier, and it might be possible to add an import to fix the problem,
 there's no way to know in advance how many libraries might define the name, but
-we'd want to proposing adding an import for each such library.
+we'd want to propose adding an import for each such library.
 
 If you are able to enumerate the possible fixes ahead of time, then you're
 better off to create one subclass of `CorrectionProducer` for each of the fixes.
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 74e88d5..4fa2db3 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -303,6 +303,8 @@
     if (element is! FunctionElement) {
       return false;
     }
+    var parent = node.parent;
+    var isInvocation = parent is MethodInvocation && parent.methodName == node;
     HighlightRegionType type;
     var isTopLevel = element.enclosingElement is CompilationUnitElement;
     if (node.inDeclarationContext()) {
@@ -311,8 +313,12 @@
           : HighlightRegionType.LOCAL_FUNCTION_DECLARATION;
     } else {
       type = isTopLevel
-          ? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE
-          : HighlightRegionType.LOCAL_FUNCTION_REFERENCE;
+          ? isInvocation
+              ? HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE
+              : HighlightRegionType.TOP_LEVEL_FUNCTION_TEAR_OFF
+          : isInvocation
+              ? HighlightRegionType.LOCAL_FUNCTION_REFERENCE
+              : HighlightRegionType.LOCAL_FUNCTION_TEAR_OFF;
     }
     return _addRegion_node(node, type);
   }
@@ -397,6 +403,8 @@
       return false;
     }
     var isStatic = element.isStatic;
+    var parent = node.parent;
+    var isInvocation = parent is MethodInvocation && parent.methodName == node;
     // OK
     HighlightRegionType type;
     if (node.inDeclarationContext()) {
@@ -407,9 +415,13 @@
       }
     } else {
       if (isStatic) {
-        type = HighlightRegionType.STATIC_METHOD_REFERENCE;
+        type = isInvocation
+            ? HighlightRegionType.STATIC_METHOD_REFERENCE
+            : HighlightRegionType.STATIC_METHOD_TEAR_OFF;
       } else {
-        type = HighlightRegionType.INSTANCE_METHOD_REFERENCE;
+        type = isInvocation
+            ? HighlightRegionType.INSTANCE_METHOD_REFERENCE
+            : HighlightRegionType.INSTANCE_METHOD_TEAR_OFF;
       }
     }
     return _addRegion_node(node, type);
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index 2d3c129..3dd47bf 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 7ad36bd..64be4e9 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -245,7 +245,8 @@
   if (kind == engine.MatchKind.INVOCATION) {
     return SearchResultKind.INVOCATION;
   }
-  if (kind == engine.MatchKind.REFERENCE) {
+  if (kind == engine.MatchKind.REFERENCE ||
+      kind == engine.MatchKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF) {
     return SearchResultKind.REFERENCE;
   }
   return SearchResultKind.UNKNOWN;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
index d34c39e..b31755a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
@@ -69,6 +69,9 @@
     return hash;
   }
 
+  bool get isConstructorTearOff =>
+      _match.kind == MatchKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF;
+
   bool get isResolved => _match.isResolved;
 
   SourceRange get range => _match.sourceRange;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index 9940c90..dc58d49 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -62,8 +62,13 @@
       references.add(_createDeclarationReference());
     }
     // update references
-    var replacement = newName.isEmpty ? '' : '.$newName';
     for (var reference in references) {
+      String replacement;
+      if (newName.isNotEmpty) {
+        replacement = '.$newName';
+      } else {
+        replacement = reference.isConstructorTearOff ? '.new' : '';
+      }
       reference.addEdit(change, replacement);
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 4b61420..362216e 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -26,6 +26,10 @@
   /// A reference to an element in which it is referenced.
   static const MatchKind REFERENCE = MatchKind('REFERENCE');
 
+  /// A tear-off reference to a constructor.
+  static const MatchKind REFERENCE_BY_CONSTRUCTOR_TEAR_OFF =
+      MatchKind('REFERENCE_BY_CONSTRUCTOR_TEAR_OFF');
+
   final String name;
 
   const MatchKind(this.name);
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index d4247e1..059c23e98 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
@@ -242,6 +242,9 @@
     if (kind == SearchResultKind.INVOCATION) {
       return MatchKind.INVOCATION;
     }
+    if (kind == SearchResultKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF) {
+      return MatchKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF;
+    }
     return MatchKind.REFERENCE;
   }
 }
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index e8a2907..a39c58d 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -1054,7 +1054,7 @@
     await prepareHighlights();
     assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_DECLARATION, 'fff() {}');
     assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff();');
-    assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_REFERENCE, 'fff;');
+    assertHasRegion(HighlightRegionType.LOCAL_FUNCTION_TEAR_OFF, 'fff;');
   }
 
   Future<void> test_LOCAL_VARIABLE() async {
@@ -1089,9 +1089,9 @@
         HighlightRegionType.INSTANCE_METHOD_DECLARATION, 'aaa() {}');
     assertHasRegion(HighlightRegionType.STATIC_METHOD_DECLARATION, 'bbb() {}');
     assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa();');
-    assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'aaa;');
+    assertHasRegion(HighlightRegionType.INSTANCE_METHOD_TEAR_OFF, 'aaa;');
     assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb();');
-    assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'bbb;');
+    assertHasRegion(HighlightRegionType.STATIC_METHOD_TEAR_OFF, 'bbb;');
   }
 
   Future<void> test_METHOD_bestType() async {
@@ -1183,6 +1183,7 @@
 fff(p) {}
 void f() {
   fff(42);
+  fff;
 }
 ''');
     await prepareHighlights();
@@ -1190,6 +1191,7 @@
         HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, 'fff(p) {}');
     assertHasRegion(
         HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, 'fff(42)');
+    assertHasRegion(HighlightRegionType.TOP_LEVEL_FUNCTION_TEAR_OFF, 'fff;');
   }
 
   Future<void> test_TOP_LEVEL_VARIABLE() async {
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 4791ace..8a094d4 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -797,6 +797,7 @@
 ///   INSTANCE_GETTER_REFERENCE
 ///   INSTANCE_METHOD_DECLARATION
 ///   INSTANCE_METHOD_REFERENCE
+///   INSTANCE_METHOD_TEAR_OFF
 ///   INSTANCE_SETTER_DECLARATION
 ///   INSTANCE_SETTER_REFERENCE
 ///   INVALID_STRING_ESCAPE
@@ -811,6 +812,7 @@
 ///   LITERAL_STRING
 ///   LOCAL_FUNCTION_DECLARATION
 ///   LOCAL_FUNCTION_REFERENCE
+///   LOCAL_FUNCTION_TEAR_OFF
 ///   LOCAL_VARIABLE
 ///   LOCAL_VARIABLE_DECLARATION
 ///   LOCAL_VARIABLE_REFERENCE
@@ -828,10 +830,12 @@
 ///   STATIC_GETTER_REFERENCE
 ///   STATIC_METHOD_DECLARATION
 ///   STATIC_METHOD_REFERENCE
+///   STATIC_METHOD_TEAR_OFF
 ///   STATIC_SETTER_DECLARATION
 ///   STATIC_SETTER_REFERENCE
 ///   TOP_LEVEL_FUNCTION_DECLARATION
 ///   TOP_LEVEL_FUNCTION_REFERENCE
+///   TOP_LEVEL_FUNCTION_TEAR_OFF
 ///   TOP_LEVEL_GETTER_DECLARATION
 ///   TOP_LEVEL_GETTER_REFERENCE
 ///   TOP_LEVEL_SETTER_DECLARATION
@@ -874,6 +878,7 @@
   'INSTANCE_GETTER_REFERENCE',
   'INSTANCE_METHOD_DECLARATION',
   'INSTANCE_METHOD_REFERENCE',
+  'INSTANCE_METHOD_TEAR_OFF',
   'INSTANCE_SETTER_DECLARATION',
   'INSTANCE_SETTER_REFERENCE',
   'INVALID_STRING_ESCAPE',
@@ -888,6 +893,7 @@
   'LITERAL_STRING',
   'LOCAL_FUNCTION_DECLARATION',
   'LOCAL_FUNCTION_REFERENCE',
+  'LOCAL_FUNCTION_TEAR_OFF',
   'LOCAL_VARIABLE',
   'LOCAL_VARIABLE_DECLARATION',
   'LOCAL_VARIABLE_REFERENCE',
@@ -905,10 +911,12 @@
   'STATIC_GETTER_REFERENCE',
   'STATIC_METHOD_DECLARATION',
   'STATIC_METHOD_REFERENCE',
+  'STATIC_METHOD_TEAR_OFF',
   'STATIC_SETTER_DECLARATION',
   'STATIC_SETTER_REFERENCE',
   'TOP_LEVEL_FUNCTION_DECLARATION',
   'TOP_LEVEL_FUNCTION_REFERENCE',
+  'TOP_LEVEL_FUNCTION_TEAR_OFF',
   'TOP_LEVEL_GETTER_DECLARATION',
   'TOP_LEVEL_GETTER_REFERENCE',
   'TOP_LEVEL_SETTER_DECLARATION',
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index ac31994..248d817 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -254,7 +254,9 @@
     // TODO(paulberry): why does the MatchKind class exist at all?  Can't we
     // use SearchResultKind inside the analysis server?
     EnumTester<MatchKind, SearchResultKind>()
-        .run(newSearchResultKind_fromEngine);
+        .run(newSearchResultKind_fromEngine, exceptions: {
+      MatchKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF: SearchResultKind.REFERENCE,
+    });
   }
 }
 
diff --git a/pkg/analysis_server/test/search/search_result_test.dart b/pkg/analysis_server/test/search/search_result_test.dart
index 25308ca..04fb0df 100644
--- a/pkg/analysis_server/test/search/search_result_test.dart
+++ b/pkg/analysis_server/test/search/search_result_test.dart
@@ -26,6 +26,10 @@
         SearchResultKind.WRITE);
     expect(newSearchResultKind_fromEngine(MatchKind.REFERENCE),
         SearchResultKind.REFERENCE);
+    expect(
+        newSearchResultKind_fromEngine(
+            MatchKind.REFERENCE_BY_CONSTRUCTOR_TEAR_OFF),
+        SearchResultKind.REFERENCE);
     expect(newSearchResultKind_fromEngine(MatchKind.INVOCATION),
         SearchResultKind.INVOCATION);
   }
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index 5057c74..c688ac2 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -101,6 +101,7 @@
 }
 main() {
   new A();
+  A.new;
 }
 ''');
     // configure refactoring
@@ -121,6 +122,7 @@
 }
 main() {
   new A.newName();
+  A.newName;
 }
 ''');
   }
@@ -136,6 +138,7 @@
 }
 main() {
   new A();
+  A.new;
 }
 ''');
     // configure refactoring
@@ -157,6 +160,7 @@
 }
 main() {
   new A.newName();
+  A.newName;
 }
 ''');
   }
@@ -173,6 +177,7 @@
 }
 main() {
   new A.test();
+  A.test;
 }
 ''');
     // configure refactoring
@@ -193,6 +198,7 @@
 }
 main() {
   new A.newName();
+  A.newName;
 }
 ''');
   }
@@ -238,6 +244,7 @@
 }
 main() {
   new A.test();
+  A.test;
 }
 ''');
     // configure refactoring
@@ -258,6 +265,7 @@
 }
 main() {
   new A();
+  A.new;
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
index 5846f51..dcf483f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/pubspec/test_support.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test/test.dart';
-import 'package:yaml/src/yaml_node.dart';
 import 'package:yaml/yaml.dart';
 
 abstract class PubspecFixTest with ResourceProviderMixin {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
index 0c42514..9cfafa7 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
@@ -57,20 +57,15 @@
     });
   }
 
-  @failingTest
   Future<void> test_complexTypeName_withoutImport() async {
     await resolveTestCode('''
 List<int> main() async {
 }
 ''');
     await assertHasFix('''
-import 'dart:async';
-
 Future<List<int>> main() async {
 }
-''', errorFilter: (error) {
-      return error.errorCode == CompileTimeErrorCode.ILLEGAL_ASYNC_RETURN_TYPE;
-    });
+''');
   }
 
   Future<void> test_importedWithPrefix() async {
@@ -101,18 +96,13 @@
     });
   }
 
-  @failingTest
   Future<void> test_simpleTypeName_withoutImport() async {
     await resolveTestCode('''
 int main() async => 0;
 ''');
     await assertHasFix('''
-import 'dart:async';
-
 Future<int> main() async => 0;
-''', errorFilter: (error) {
-      return error.errorCode == CompileTimeErrorCode.ILLEGAL_ASYNC_RETURN_TYPE;
-    });
+''');
   }
 
   Future<void> test_withLibraryDirective_withImport() async {
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 01b222b..fe567c5 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -93,6 +93,8 @@
 
   public static final String INSTANCE_METHOD_REFERENCE = "INSTANCE_METHOD_REFERENCE";
 
+  public static final String INSTANCE_METHOD_TEAR_OFF = "INSTANCE_METHOD_TEAR_OFF";
+
   public static final String INSTANCE_SETTER_DECLARATION = "INSTANCE_SETTER_DECLARATION";
 
   public static final String INSTANCE_SETTER_REFERENCE = "INSTANCE_SETTER_REFERENCE";
@@ -121,6 +123,8 @@
 
   public static final String LOCAL_FUNCTION_REFERENCE = "LOCAL_FUNCTION_REFERENCE";
 
+  public static final String LOCAL_FUNCTION_TEAR_OFF = "LOCAL_FUNCTION_TEAR_OFF";
+
   /**
    * Deprecated - no longer sent.
    */
@@ -179,6 +183,8 @@
 
   public static final String STATIC_METHOD_REFERENCE = "STATIC_METHOD_REFERENCE";
 
+  public static final String STATIC_METHOD_TEAR_OFF = "STATIC_METHOD_TEAR_OFF";
+
   public static final String STATIC_SETTER_DECLARATION = "STATIC_SETTER_DECLARATION";
 
   public static final String STATIC_SETTER_REFERENCE = "STATIC_SETTER_REFERENCE";
@@ -187,6 +193,8 @@
 
   public static final String TOP_LEVEL_FUNCTION_REFERENCE = "TOP_LEVEL_FUNCTION_REFERENCE";
 
+  public static final String TOP_LEVEL_FUNCTION_TEAR_OFF = "TOP_LEVEL_FUNCTION_TEAR_OFF";
+
   public static final String TOP_LEVEL_GETTER_DECLARATION = "TOP_LEVEL_GETTER_DECLARATION";
 
   public static final String TOP_LEVEL_GETTER_REFERENCE = "TOP_LEVEL_GETTER_REFERENCE";
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
index 2900b89..0675a7a 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
@@ -1877,6 +1877,7 @@
 ///   INSTANCE_GETTER_REFERENCE
 ///   INSTANCE_METHOD_DECLARATION
 ///   INSTANCE_METHOD_REFERENCE
+///   INSTANCE_METHOD_TEAR_OFF
 ///   INSTANCE_SETTER_DECLARATION
 ///   INSTANCE_SETTER_REFERENCE
 ///   INVALID_STRING_ESCAPE
@@ -1891,6 +1892,7 @@
 ///   LITERAL_STRING
 ///   LOCAL_FUNCTION_DECLARATION
 ///   LOCAL_FUNCTION_REFERENCE
+///   LOCAL_FUNCTION_TEAR_OFF
 ///   LOCAL_VARIABLE
 ///   LOCAL_VARIABLE_DECLARATION
 ///   LOCAL_VARIABLE_REFERENCE
@@ -1908,10 +1910,12 @@
 ///   STATIC_GETTER_REFERENCE
 ///   STATIC_METHOD_DECLARATION
 ///   STATIC_METHOD_REFERENCE
+///   STATIC_METHOD_TEAR_OFF
 ///   STATIC_SETTER_DECLARATION
 ///   STATIC_SETTER_REFERENCE
 ///   TOP_LEVEL_FUNCTION_DECLARATION
 ///   TOP_LEVEL_FUNCTION_REFERENCE
+///   TOP_LEVEL_FUNCTION_TEAR_OFF
 ///   TOP_LEVEL_GETTER_DECLARATION
 ///   TOP_LEVEL_GETTER_REFERENCE
 ///   TOP_LEVEL_SETTER_DECLARATION
@@ -2017,6 +2021,9 @@
   static const HighlightRegionType INSTANCE_METHOD_REFERENCE =
       HighlightRegionType._('INSTANCE_METHOD_REFERENCE');
 
+  static const HighlightRegionType INSTANCE_METHOD_TEAR_OFF =
+      HighlightRegionType._('INSTANCE_METHOD_TEAR_OFF');
+
   static const HighlightRegionType INSTANCE_SETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_SETTER_DECLARATION');
 
@@ -2057,6 +2064,9 @@
   static const HighlightRegionType LOCAL_FUNCTION_REFERENCE =
       HighlightRegionType._('LOCAL_FUNCTION_REFERENCE');
 
+  static const HighlightRegionType LOCAL_FUNCTION_TEAR_OFF =
+      HighlightRegionType._('LOCAL_FUNCTION_TEAR_OFF');
+
   /// Deprecated - no longer sent.
   static const HighlightRegionType LOCAL_VARIABLE =
       HighlightRegionType._('LOCAL_VARIABLE');
@@ -2115,6 +2125,9 @@
   static const HighlightRegionType STATIC_METHOD_REFERENCE =
       HighlightRegionType._('STATIC_METHOD_REFERENCE');
 
+  static const HighlightRegionType STATIC_METHOD_TEAR_OFF =
+      HighlightRegionType._('STATIC_METHOD_TEAR_OFF');
+
   static const HighlightRegionType STATIC_SETTER_DECLARATION =
       HighlightRegionType._('STATIC_SETTER_DECLARATION');
 
@@ -2127,6 +2140,9 @@
   static const HighlightRegionType TOP_LEVEL_FUNCTION_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_REFERENCE');
 
+  static const HighlightRegionType TOP_LEVEL_FUNCTION_TEAR_OFF =
+      HighlightRegionType._('TOP_LEVEL_FUNCTION_TEAR_OFF');
+
   static const HighlightRegionType TOP_LEVEL_GETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_GETTER_DECLARATION');
 
@@ -2189,6 +2205,7 @@
     INSTANCE_GETTER_REFERENCE,
     INSTANCE_METHOD_DECLARATION,
     INSTANCE_METHOD_REFERENCE,
+    INSTANCE_METHOD_TEAR_OFF,
     INSTANCE_SETTER_DECLARATION,
     INSTANCE_SETTER_REFERENCE,
     INVALID_STRING_ESCAPE,
@@ -2203,6 +2220,7 @@
     LITERAL_STRING,
     LOCAL_FUNCTION_DECLARATION,
     LOCAL_FUNCTION_REFERENCE,
+    LOCAL_FUNCTION_TEAR_OFF,
     LOCAL_VARIABLE,
     LOCAL_VARIABLE_DECLARATION,
     LOCAL_VARIABLE_REFERENCE,
@@ -2220,10 +2238,12 @@
     STATIC_GETTER_REFERENCE,
     STATIC_METHOD_DECLARATION,
     STATIC_METHOD_REFERENCE,
+    STATIC_METHOD_TEAR_OFF,
     STATIC_SETTER_DECLARATION,
     STATIC_SETTER_REFERENCE,
     TOP_LEVEL_FUNCTION_DECLARATION,
     TOP_LEVEL_FUNCTION_REFERENCE,
+    TOP_LEVEL_FUNCTION_TEAR_OFF,
     TOP_LEVEL_GETTER_DECLARATION,
     TOP_LEVEL_GETTER_REFERENCE,
     TOP_LEVEL_SETTER_DECLARATION,
@@ -2303,6 +2323,8 @@
         return INSTANCE_METHOD_DECLARATION;
       case 'INSTANCE_METHOD_REFERENCE':
         return INSTANCE_METHOD_REFERENCE;
+      case 'INSTANCE_METHOD_TEAR_OFF':
+        return INSTANCE_METHOD_TEAR_OFF;
       case 'INSTANCE_SETTER_DECLARATION':
         return INSTANCE_SETTER_DECLARATION;
       case 'INSTANCE_SETTER_REFERENCE':
@@ -2331,6 +2353,8 @@
         return LOCAL_FUNCTION_DECLARATION;
       case 'LOCAL_FUNCTION_REFERENCE':
         return LOCAL_FUNCTION_REFERENCE;
+      case 'LOCAL_FUNCTION_TEAR_OFF':
+        return LOCAL_FUNCTION_TEAR_OFF;
       case 'LOCAL_VARIABLE':
         return LOCAL_VARIABLE;
       case 'LOCAL_VARIABLE_DECLARATION':
@@ -2365,6 +2389,8 @@
         return STATIC_METHOD_DECLARATION;
       case 'STATIC_METHOD_REFERENCE':
         return STATIC_METHOD_REFERENCE;
+      case 'STATIC_METHOD_TEAR_OFF':
+        return STATIC_METHOD_TEAR_OFF;
       case 'STATIC_SETTER_DECLARATION':
         return STATIC_SETTER_DECLARATION;
       case 'STATIC_SETTER_REFERENCE':
@@ -2373,6 +2399,8 @@
         return TOP_LEVEL_FUNCTION_DECLARATION;
       case 'TOP_LEVEL_FUNCTION_REFERENCE':
         return TOP_LEVEL_FUNCTION_REFERENCE;
+      case 'TOP_LEVEL_FUNCTION_TEAR_OFF':
+        return TOP_LEVEL_FUNCTION_TEAR_OFF;
       case 'TOP_LEVEL_GETTER_DECLARATION':
         return TOP_LEVEL_GETTER_DECLARATION;
       case 'TOP_LEVEL_GETTER_REFERENCE':
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index d11b587..9c671fc 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -142,6 +142,7 @@
   CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
   CompileTimeErrorCode.CONST_WITH_NON_TYPE,
   CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
+  CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF,
   CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
   CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
   CompileTimeErrorCode.CONTINUE_LABEL_ON_SWITCH,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 1063912..8f85644 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 175;
+  static const int DATA_VERSION = 176;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index c2d09bb..f89ac53 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -114,6 +114,15 @@
   }
 
   @override
+  void visitConstructorReference(ConstructorReference node) {
+    super.visitConstructorReference(node);
+    if (node.inConstantContext) {
+      _checkForConstWithTypeParameters(node.constructorName.type,
+          CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF);
+    }
+  }
+
+  @override
   void visitFunctionExpression(FunctionExpression node) {
     super.visitFunctionExpression(node);
     _validateDefaultValues(node.parameters);
@@ -123,7 +132,8 @@
   void visitInstanceCreationExpression(InstanceCreationExpression node) {
     if (node.isConst) {
       TypeName typeName = node.constructorName.type;
-      _checkForConstWithTypeParameters(typeName);
+      _checkForConstWithTypeParameters(
+          typeName, CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS);
 
       node.argumentList.accept(this);
 
@@ -261,23 +271,44 @@
   /// Verify that the given [type] does not reference any type parameters.
   ///
   /// See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS].
-  void _checkForConstWithTypeParameters(TypeAnnotation type) {
-    // something wrong with AST
-    if (type is! TypeName) {
-      return;
-    }
-    TypeName typeName = type;
-    Identifier name = typeName.name;
-    // should not be a type parameter
-    if (name.staticElement is TypeParameterElement) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name);
-    }
-    // check type arguments
-    var typeArguments = typeName.typeArguments;
-    if (typeArguments != null) {
-      for (TypeAnnotation argument in typeArguments.arguments) {
-        _checkForConstWithTypeParameters(argument);
+  void _checkForConstWithTypeParameters(
+      TypeAnnotation type, ErrorCode errorCode) {
+    if (type is TypeName) {
+      Identifier name = type.name;
+      // Should not be a type parameter.
+      if (name.staticElement is TypeParameterElement) {
+        _errorReporter.reportErrorForNode(errorCode, name);
+      }
+      // Check type arguments.
+      var typeArguments = type.typeArguments;
+      if (typeArguments != null) {
+        for (TypeAnnotation argument in typeArguments.arguments) {
+          _checkForConstWithTypeParameters(argument, errorCode);
+        }
+      }
+    } else if (type is GenericFunctionType) {
+      var returnType = type.returnType;
+      if (returnType != null) {
+        _checkForConstWithTypeParameters(returnType, errorCode);
+      }
+      for (var parameter in type.parameters.parameters) {
+        // [parameter] cannot be a [DefaultFormalParameter], a
+        // [FieldFormalParameter], nor a [FunctionTypedFormalParameter].
+        if (parameter is SimpleFormalParameter) {
+          var parameterType = parameter.type;
+          if (parameterType != null) {
+            _checkForConstWithTypeParameters(parameterType, errorCode);
+          }
+        }
+      }
+      var typeParameters = type.typeParameters;
+      if (typeParameters != null) {
+        for (var typeParameter in typeParameters.typeParameters) {
+          var bound = typeParameter.bound;
+          if (bound != null) {
+            _checkForConstWithTypeParameters(bound, errorCode);
+          }
+        }
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 0ea830f..f7988fd1 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2887,6 +2887,18 @@
           hasPublishedDocs: true);
 
   /**
+   * No parameters.
+   */
+  static const CompileTimeErrorCode
+      CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF = CompileTimeErrorCode(
+          'CONST_WITH_TYPE_PARAMETERS',
+          "A constant constructor tearoff can't use a type parameter as a type "
+              "argument.",
+          correction: "Try replacing the type parameter with a different type.",
+          uniqueName: 'CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF',
+          hasPublishedDocs: true);
+
+  /**
    * 16.12.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
    * a constant constructor declared by the type <i>T</i>.
    *
diff --git a/pkg/analyzer/lib/src/error/use_result_verifier.dart b/pkg/analyzer/lib/src/error/use_result_verifier.dart
index cc2d3bf..fd0eaed 100644
--- a/pkg/analyzer/lib/src/error/use_result_verifier.dart
+++ b/pkg/analyzer/lib/src/error/use_result_verifier.dart
@@ -140,9 +140,11 @@
       return false;
     }
 
-    if (parent is ParenthesizedExpression ||
-        parent is ConditionalExpression ||
-        parent is CascadeExpression) {
+    if (parent is CascadeExpression) {
+      return parent.target == node;
+    }
+
+    if (parent is ParenthesizedExpression || parent is ConditionalExpression) {
       return _isUsed(parent);
     }
 
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3b579a5..ef26b14 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1237,13 +1237,8 @@
 
   @override
   void visitConstructorName(ConstructorName node) {
-    //
-    // We do not visit either the type name, because it won't be visited anyway,
-    // or the name, because it needs to be visited in the context of the
-    // constructor name.
-    //
+    node.type.accept(this);
     node.accept(elementResolver);
-    node.accept(typeAnalyzer);
   }
 
   @override
@@ -2001,7 +1996,13 @@
   }
 
   @override
-  void visitTypeName(TypeName node) {}
+  void visitTypeName(TypeName node) {
+    // All TypeName(s) are already resolved, so we don't resolve it here.
+    // But there might be type arguments with Expression(s), such as default
+    // values for formal parameters of GenericFunctionType(s). These are
+    // invalid, but if they exist, they should be resolved.
+    node.typeArguments?.accept(this);
+  }
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index 19f6fce..6a7dec8 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -187,6 +187,9 @@
   @override
   final String root;
 
+  /// Either `blaze` or `bazel`.
+  final String symlinkPrefix;
+
   /// The absolute path to the optional read only workspace root, in the
   /// `READONLY` folder if a git-based workspace, or `null`.
   final String? readonly;
@@ -214,6 +217,7 @@
   BazelWorkspace._(
     this.provider,
     this.root,
+    this.symlinkPrefix,
     this.readonly,
     this.binPaths,
     this.genfiles, {
@@ -260,9 +264,14 @@
       if (relative == '.') {
         return null;
       }
-      // First check genfiles and bin directories
-      var generatedCandidates = <String>[genfiles, ...binPaths]
-          .map((prefix) => context.join(prefix, relative));
+      // First check genfiles and bin directories. Note that we always use the
+      // symlinks and not the [binPaths] or [genfiles] to make sure we use the
+      // files corresponding to the most recent build configuration and get
+      // consistent view of all the generated files.
+      var generatedCandidates = [
+        '$symlinkPrefix-genfiles',
+        '$symlinkPrefix-bin'
+      ].map((prefix) => context.join(root, context.join(prefix, relative)));
       for (var path in generatedCandidates) {
         File file = provider.getFile(path);
         if (file.exists) {
@@ -454,8 +463,8 @@
           String symlinkPrefix =
               _findSymlinkPrefix(provider, root, binPaths: binPaths);
           binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
-          return BazelWorkspace._(provider, root, readonlyRoot, binPaths,
-              context.join(root, '$symlinkPrefix-genfiles'),
+          return BazelWorkspace._(provider, root, symlinkPrefix, readonlyRoot,
+              binPaths, context.join(root, '$symlinkPrefix-genfiles'),
               lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
         }
       }
@@ -467,7 +476,12 @@
         String symlinkPrefix =
             _findSymlinkPrefix(provider, root, binPaths: binPaths);
         binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
-        return BazelWorkspace._(provider, root, null /* readonly */, binPaths,
+        return BazelWorkspace._(
+            provider,
+            root,
+            symlinkPrefix,
+            null /* readonly */,
+            binPaths,
             context.join(root, '$symlinkPrefix-genfiles'),
             lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
       }
@@ -479,7 +493,12 @@
         String symlinkPrefix =
             _findSymlinkPrefix(provider, root, binPaths: binPaths);
         binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
-        return BazelWorkspace._(provider, root, null /* readonly */, binPaths,
+        return BazelWorkspace._(
+            provider,
+            root,
+            symlinkPrefix,
+            null /* readonly */,
+            binPaths,
             context.join(root, '$symlinkPrefix-genfiles'),
             lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
       }
diff --git a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
index d1e3f26..cd56312 100644
--- a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
@@ -32,7 +32,7 @@
   final List<String> _candidates;
 
   /// The time of last modification of the file under [_validPath].
-  _TimestampAndLength? _lastModified;
+  _ModifiedInfo? _lastModified;
 
   /// The resource provider used for polling the files.
   final ResourceProvider _provider;
@@ -46,7 +46,7 @@
   /// Checks if the file corresponding to the watched path has changed and
   /// returns the event or `null` if nothing changed.
   WatchEvent? poll() {
-    _TimestampAndLength? modified;
+    _ModifiedInfo? modified;
     if (_validPath == null) {
       var info = _pollAll();
       if (info != null) {
@@ -107,22 +107,23 @@
 
   /// Returns the modified time of the path or `null` if the file does not
   /// exist.
-  _TimestampAndLength? _pollOne(String path) {
+  _ModifiedInfo? _pollOne(String path) {
     try {
       // This might seem a bit convoluted but is necessary to deal with a
       // symlink to a directory (e.g., `bazel-bin`).
-      var resource = _provider.getResource(
-          _provider.getResource(path).resolveSymbolicLinksSync().path);
-      if (resource is File) {
-        var timestamp = resource.modificationStamp;
-        var length = resource.lengthSync;
-        return _TimestampAndLength(timestamp, length);
-      } else if (resource is Folder) {
+
+      var pathResource = _provider.getResource(path);
+      var symlinkTarget = pathResource.resolveSymbolicLinksSync().path;
+      var resolvedResource = _provider.getResource(symlinkTarget);
+      if (resolvedResource is File) {
+        var timestamp = resolvedResource.modificationStamp;
+        var length = resolvedResource.lengthSync;
+        return _ModifiedInfo(timestamp, length, symlinkTarget);
+      } else if (resolvedResource is Folder) {
         // `ResourceProvider` doesn't currently support getting timestamps of a
-        // folder, so we use a dummy value here. But it's still useful: this
-        // will correctly generate `ADD` or `REMOVE` events (we'll be just
-        // unable to generate any `CHANGE` events).
-        return _TimestampAndLength(0, 0);
+        // folder, so we use a dummy value here. But this shouldn't really
+        // matter, since the `symlinkTarget` should detect any modifications.
+        return _ModifiedInfo(0, 0, symlinkTarget);
       }
     } on FileSystemException catch (_) {
       // File doesn't exist, so return null.
@@ -416,7 +417,7 @@
 
 class FileInfo {
   String path;
-  _TimestampAndLength modified;
+  _ModifiedInfo modified;
   FileInfo(this.path, this.modified);
 }
 
@@ -524,6 +525,46 @@
   }
 }
 
+/// Data used to determines if a file has changed.
+///
+/// This turns out to be important for tracking files that change a lot, like
+/// the `command.log` that we use to detect the finished build.  Bazel writes to
+/// the file continuously and because the resolution of a timestamp is pretty
+/// low, it's quite possible to receive the same timestamp even though the file
+/// has changed.  We use its length to remedy that.  It's not perfect (for that
+/// we'd have to compute the hash), but it should be reasonable trade-off (to
+/// avoid any performance impact from reading and hashing the file).
+class _ModifiedInfo {
+  final int timestamp;
+  final int length;
+
+  /// Stores the resolved path in case a symlink or just the path for ordinary
+  /// files.
+  final String symlinkTarget;
+
+  _ModifiedInfo(this.timestamp, this.length, this.symlinkTarget);
+
+  @override
+  int get hashCode =>
+      // We don't really need to compute hashes, just check the equality. But
+      // throw in case someone expects this to work.
+      throw UnimplementedError(
+          '_ModifiedInfo.hashCode has not been implemented yet');
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! _ModifiedInfo) return false;
+    return timestamp == other.timestamp &&
+        length == other.length &&
+        symlinkTarget == other.symlinkTarget;
+  }
+
+  // For debugging only.
+  @override
+  String toString() => '_ModifiedInfo('
+      'timestamp=$timestamp, length=$length, symlinkTarget=$symlinkTarget)';
+}
+
 class _Multiset<T> {
   final _counts = <T, int>{};
 
@@ -562,36 +603,3 @@
 
   _PerWorkspaceData(this.trigger, this.pollSubscription);
 }
-
-/// Stores the timestamp of a file and its length.
-///
-/// This turns out to be important for tracking files that change a lot, like
-/// the `command.log` that we use to detect the finished build.  Bazel writes to
-/// the file continuously and because the resolution of a timestamp is pretty
-/// low, it's quite possible to receive the same timestamp even though the file
-/// has changed.  We use its length to remedy that.  It's not perfect (for that
-/// we'd have to compute the hash), but it should be reasonable trade-off (to
-/// avoid any performance impact from reading and hashing the file).
-class _TimestampAndLength {
-  final int timestamp;
-  final int length;
-  _TimestampAndLength(this.timestamp, this.length);
-
-  @override
-  int get hashCode =>
-      // We don't really need to compute hashes, just check the equality. But
-      // throw in case someone expects this to work.
-      throw UnimplementedError(
-          '_TimestampAndLength.hashCode has not been implemented yet');
-
-  @override
-  bool operator ==(Object other) {
-    if (other is! _TimestampAndLength) return false;
-    return timestamp == other.timestamp && length == other.length;
-  }
-
-  // For debugging only.
-  @override
-  String toString() =>
-      '_TimestampAndLength(timestamp=$timestamp, length=$length)';
-}
diff --git a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
index ea1ef186..ebd3043 100644
--- a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
@@ -9,33 +9,139 @@
 
 main() {
   defineReflectiveSuite(() {
+    defineReflectiveTests(ConstWithTypeParametersConstructorTearoffTest);
     defineReflectiveTests(ConstWithTypeParametersTest);
   });
 }
 
 @reflectiveTest
-class ConstWithTypeParametersTest extends PubPackageResolutionTest {
+class ConstWithTypeParametersConstructorTearoffTest
+    extends PubPackageResolutionTest {
   test_direct() async {
-    await assertErrorsInCode(r'''
+    await assertErrorsInCode('''
 class A<T> {
-  static const V = const A<T>();
-  const A();
+  void m() {
+    const c = A<T>.new;
+  }
 }
 ''', [
-      error(CompileTimeErrorCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 40, 1),
-      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 40, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 36, 1),
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF,
+          42, 1),
     ]);
   }
 
   test_indirect() async {
-    await assertErrorsInCode(r'''
+    await assertErrorsInCode('''
 class A<T> {
-  static const V = const A<List<T>>();
-  const A();
+  void m() {
+    const c = A<List<T>>.new;
+  }
 }
 ''', [
-      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 45, 1),
-      error(CompileTimeErrorCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 45, 1),
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 36, 1),
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF,
+          47, 1),
     ]);
   }
+
+  test_nonConst() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  void m() {
+    A<T>.new;
+  }
+}
+''');
+  }
+}
+
+@reflectiveTest
+class ConstWithTypeParametersTest extends PubPackageResolutionTest {
+  test_direct() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    const A<T>();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 51, 1),
+    ]);
+  }
+
+  test_indirect() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    const A<List<T>>();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 56, 1),
+    ]);
+  }
+
+  test_indirect_functionType_returnType() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    const A<T Function()>();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 51, 1),
+    ]);
+  }
+
+  test_indirect_functionType_simpleParameter() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    const A<void Function(T)>();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 65, 1),
+    ]);
+  }
+
+  test_indirect_functionType_typeParameter() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    const A<void Function<U>()>();
+  }
+}
+''');
+  }
+
+  test_indirect_functionType_typeParameter_typeParameterBound() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    const A<void Function<U extends T>()>();
+  }
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, 75, 1),
+    ]);
+  }
+
+  test_nonConstContext() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  const A();
+  void m() {
+    A<T>();
+  }
+}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/default_value_in_function_type_test.dart b/pkg/analyzer/test/src/diagnostics/default_value_in_function_type_test.dart
index 19c3909..46af94a 100644
--- a/pkg/analyzer/test/src/diagnostics/default_value_in_function_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/default_value_in_function_type_test.dart
@@ -58,4 +58,18 @@
       error(ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE, 13, 1),
     ]);
   }
+
+  test_typeArgument_ofInstanceCreation() async {
+    await assertErrorsInCode('''
+class A<T> {}
+
+void f() {
+  A<void Function([int x = 42])>();
+}
+''', [
+      error(ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE, 51, 1),
+    ]);
+    // The expression is resolved, even if it is invalid.
+    assertType(findNode.integerLiteral('42'), 'int');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
index 02a7888..5d1c5a6 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_result_test.dart
@@ -568,6 +568,21 @@
 ''');
   }
 
+  test_method_result_unassigned_parameterNotDefinedAndCascaded() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+class A {
+  @UseResult.unless(parameterDefined: 'value')
+  int foo([int? value]) => value ?? 0;
+}
+
+void main() {
+  A().foo()..toString();
+}
+''');
+  }
+
   test_topLevelFunction_result_assigned() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -667,21 +682,6 @@
     ]);
   }
 
-  test_topLevelFunction_result_unassigned_cascade() async {
-    await assertErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-@useResult
-int foo() => 0;
-
-void main() {
-  foo()..toString();
-}
-''', [
-      error(HintCode.UNUSED_RESULT, 78, 3),
-    ]);
-  }
-
   test_topLevelFunction_result_unassigned_parameterDefined() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -725,6 +725,19 @@
     ]);
   }
 
+  test_topLevelFunction_result_used_in_cascade() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@useResult
+int foo() => 0;
+
+void main() {
+  foo()..toString();
+}
+''');
+  }
+
   test_topLevelVariable_assigned() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index a6571b2..60b5987 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -2644,6 +2644,8 @@
 
 ### const_with_type_parameters
 
+_A constant constructor tearoff can't use a type parameter as a type argument._
+
 _A constant creation can't use a type parameter as a type argument._
 
 #### Description
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 83c8834..cba223d 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1403,7 +1403,7 @@
       </dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
         
         <p>Deprecated - no longer sent.</p>
-      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
+      </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_METHOD_TEAR_OFF</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_FUNCTION_TEAR_OFF</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
         
         <p>Deprecated - no longer sent.</p>
       </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
@@ -1427,7 +1427,7 @@
       </dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
         
         <p>Deprecated - no longer sent.</p>
-      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_ALIAS</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
+      </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_METHOD_TEAR_OFF</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_TEAR_OFF</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_ALIAS</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
     <p>
       This object matches the format and documentation of the Entry object
       documented in the
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 83ecb6f..65b6704 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -1877,6 +1877,7 @@
 ///   INSTANCE_GETTER_REFERENCE
 ///   INSTANCE_METHOD_DECLARATION
 ///   INSTANCE_METHOD_REFERENCE
+///   INSTANCE_METHOD_TEAR_OFF
 ///   INSTANCE_SETTER_DECLARATION
 ///   INSTANCE_SETTER_REFERENCE
 ///   INVALID_STRING_ESCAPE
@@ -1891,6 +1892,7 @@
 ///   LITERAL_STRING
 ///   LOCAL_FUNCTION_DECLARATION
 ///   LOCAL_FUNCTION_REFERENCE
+///   LOCAL_FUNCTION_TEAR_OFF
 ///   LOCAL_VARIABLE
 ///   LOCAL_VARIABLE_DECLARATION
 ///   LOCAL_VARIABLE_REFERENCE
@@ -1908,10 +1910,12 @@
 ///   STATIC_GETTER_REFERENCE
 ///   STATIC_METHOD_DECLARATION
 ///   STATIC_METHOD_REFERENCE
+///   STATIC_METHOD_TEAR_OFF
 ///   STATIC_SETTER_DECLARATION
 ///   STATIC_SETTER_REFERENCE
 ///   TOP_LEVEL_FUNCTION_DECLARATION
 ///   TOP_LEVEL_FUNCTION_REFERENCE
+///   TOP_LEVEL_FUNCTION_TEAR_OFF
 ///   TOP_LEVEL_GETTER_DECLARATION
 ///   TOP_LEVEL_GETTER_REFERENCE
 ///   TOP_LEVEL_SETTER_DECLARATION
@@ -2017,6 +2021,9 @@
   static const HighlightRegionType INSTANCE_METHOD_REFERENCE =
       HighlightRegionType._('INSTANCE_METHOD_REFERENCE');
 
+  static const HighlightRegionType INSTANCE_METHOD_TEAR_OFF =
+      HighlightRegionType._('INSTANCE_METHOD_TEAR_OFF');
+
   static const HighlightRegionType INSTANCE_SETTER_DECLARATION =
       HighlightRegionType._('INSTANCE_SETTER_DECLARATION');
 
@@ -2057,6 +2064,9 @@
   static const HighlightRegionType LOCAL_FUNCTION_REFERENCE =
       HighlightRegionType._('LOCAL_FUNCTION_REFERENCE');
 
+  static const HighlightRegionType LOCAL_FUNCTION_TEAR_OFF =
+      HighlightRegionType._('LOCAL_FUNCTION_TEAR_OFF');
+
   /// Deprecated - no longer sent.
   static const HighlightRegionType LOCAL_VARIABLE =
       HighlightRegionType._('LOCAL_VARIABLE');
@@ -2115,6 +2125,9 @@
   static const HighlightRegionType STATIC_METHOD_REFERENCE =
       HighlightRegionType._('STATIC_METHOD_REFERENCE');
 
+  static const HighlightRegionType STATIC_METHOD_TEAR_OFF =
+      HighlightRegionType._('STATIC_METHOD_TEAR_OFF');
+
   static const HighlightRegionType STATIC_SETTER_DECLARATION =
       HighlightRegionType._('STATIC_SETTER_DECLARATION');
 
@@ -2127,6 +2140,9 @@
   static const HighlightRegionType TOP_LEVEL_FUNCTION_REFERENCE =
       HighlightRegionType._('TOP_LEVEL_FUNCTION_REFERENCE');
 
+  static const HighlightRegionType TOP_LEVEL_FUNCTION_TEAR_OFF =
+      HighlightRegionType._('TOP_LEVEL_FUNCTION_TEAR_OFF');
+
   static const HighlightRegionType TOP_LEVEL_GETTER_DECLARATION =
       HighlightRegionType._('TOP_LEVEL_GETTER_DECLARATION');
 
@@ -2189,6 +2205,7 @@
     INSTANCE_GETTER_REFERENCE,
     INSTANCE_METHOD_DECLARATION,
     INSTANCE_METHOD_REFERENCE,
+    INSTANCE_METHOD_TEAR_OFF,
     INSTANCE_SETTER_DECLARATION,
     INSTANCE_SETTER_REFERENCE,
     INVALID_STRING_ESCAPE,
@@ -2203,6 +2220,7 @@
     LITERAL_STRING,
     LOCAL_FUNCTION_DECLARATION,
     LOCAL_FUNCTION_REFERENCE,
+    LOCAL_FUNCTION_TEAR_OFF,
     LOCAL_VARIABLE,
     LOCAL_VARIABLE_DECLARATION,
     LOCAL_VARIABLE_REFERENCE,
@@ -2220,10 +2238,12 @@
     STATIC_GETTER_REFERENCE,
     STATIC_METHOD_DECLARATION,
     STATIC_METHOD_REFERENCE,
+    STATIC_METHOD_TEAR_OFF,
     STATIC_SETTER_DECLARATION,
     STATIC_SETTER_REFERENCE,
     TOP_LEVEL_FUNCTION_DECLARATION,
     TOP_LEVEL_FUNCTION_REFERENCE,
+    TOP_LEVEL_FUNCTION_TEAR_OFF,
     TOP_LEVEL_GETTER_DECLARATION,
     TOP_LEVEL_GETTER_REFERENCE,
     TOP_LEVEL_SETTER_DECLARATION,
@@ -2303,6 +2323,8 @@
         return INSTANCE_METHOD_DECLARATION;
       case 'INSTANCE_METHOD_REFERENCE':
         return INSTANCE_METHOD_REFERENCE;
+      case 'INSTANCE_METHOD_TEAR_OFF':
+        return INSTANCE_METHOD_TEAR_OFF;
       case 'INSTANCE_SETTER_DECLARATION':
         return INSTANCE_SETTER_DECLARATION;
       case 'INSTANCE_SETTER_REFERENCE':
@@ -2331,6 +2353,8 @@
         return LOCAL_FUNCTION_DECLARATION;
       case 'LOCAL_FUNCTION_REFERENCE':
         return LOCAL_FUNCTION_REFERENCE;
+      case 'LOCAL_FUNCTION_TEAR_OFF':
+        return LOCAL_FUNCTION_TEAR_OFF;
       case 'LOCAL_VARIABLE':
         return LOCAL_VARIABLE;
       case 'LOCAL_VARIABLE_DECLARATION':
@@ -2365,6 +2389,8 @@
         return STATIC_METHOD_DECLARATION;
       case 'STATIC_METHOD_REFERENCE':
         return STATIC_METHOD_REFERENCE;
+      case 'STATIC_METHOD_TEAR_OFF':
+        return STATIC_METHOD_TEAR_OFF;
       case 'STATIC_SETTER_DECLARATION':
         return STATIC_SETTER_DECLARATION;
       case 'STATIC_SETTER_REFERENCE':
@@ -2373,6 +2399,8 @@
         return TOP_LEVEL_FUNCTION_DECLARATION;
       case 'TOP_LEVEL_FUNCTION_REFERENCE':
         return TOP_LEVEL_FUNCTION_REFERENCE;
+      case 'TOP_LEVEL_FUNCTION_TEAR_OFF':
+        return TOP_LEVEL_FUNCTION_TEAR_OFF;
       case 'TOP_LEVEL_GETTER_DECLARATION':
         return TOP_LEVEL_GETTER_DECLARATION;
       case 'TOP_LEVEL_GETTER_REFERENCE':
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index a4aade5..bb1ed53 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -391,6 +391,7 @@
 ///   INSTANCE_GETTER_REFERENCE
 ///   INSTANCE_METHOD_DECLARATION
 ///   INSTANCE_METHOD_REFERENCE
+///   INSTANCE_METHOD_TEAR_OFF
 ///   INSTANCE_SETTER_DECLARATION
 ///   INSTANCE_SETTER_REFERENCE
 ///   INVALID_STRING_ESCAPE
@@ -405,6 +406,7 @@
 ///   LITERAL_STRING
 ///   LOCAL_FUNCTION_DECLARATION
 ///   LOCAL_FUNCTION_REFERENCE
+///   LOCAL_FUNCTION_TEAR_OFF
 ///   LOCAL_VARIABLE
 ///   LOCAL_VARIABLE_DECLARATION
 ///   LOCAL_VARIABLE_REFERENCE
@@ -422,10 +424,12 @@
 ///   STATIC_GETTER_REFERENCE
 ///   STATIC_METHOD_DECLARATION
 ///   STATIC_METHOD_REFERENCE
+///   STATIC_METHOD_TEAR_OFF
 ///   STATIC_SETTER_DECLARATION
 ///   STATIC_SETTER_REFERENCE
 ///   TOP_LEVEL_FUNCTION_DECLARATION
 ///   TOP_LEVEL_FUNCTION_REFERENCE
+///   TOP_LEVEL_FUNCTION_TEAR_OFF
 ///   TOP_LEVEL_GETTER_DECLARATION
 ///   TOP_LEVEL_GETTER_REFERENCE
 ///   TOP_LEVEL_SETTER_DECLARATION
@@ -468,6 +472,7 @@
   'INSTANCE_GETTER_REFERENCE',
   'INSTANCE_METHOD_DECLARATION',
   'INSTANCE_METHOD_REFERENCE',
+  'INSTANCE_METHOD_TEAR_OFF',
   'INSTANCE_SETTER_DECLARATION',
   'INSTANCE_SETTER_REFERENCE',
   'INVALID_STRING_ESCAPE',
@@ -482,6 +487,7 @@
   'LITERAL_STRING',
   'LOCAL_FUNCTION_DECLARATION',
   'LOCAL_FUNCTION_REFERENCE',
+  'LOCAL_FUNCTION_TEAR_OFF',
   'LOCAL_VARIABLE',
   'LOCAL_VARIABLE_DECLARATION',
   'LOCAL_VARIABLE_REFERENCE',
@@ -499,10 +505,12 @@
   'STATIC_GETTER_REFERENCE',
   'STATIC_METHOD_DECLARATION',
   'STATIC_METHOD_REFERENCE',
+  'STATIC_METHOD_TEAR_OFF',
   'STATIC_SETTER_DECLARATION',
   'STATIC_SETTER_REFERENCE',
   'TOP_LEVEL_FUNCTION_DECLARATION',
   'TOP_LEVEL_FUNCTION_REFERENCE',
+  'TOP_LEVEL_FUNCTION_TEAR_OFF',
   'TOP_LEVEL_GETTER_DECLARATION',
   'TOP_LEVEL_GETTER_REFERENCE',
   'TOP_LEVEL_SETTER_DECLARATION',
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index a802f72..bb13ac5 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -744,6 +744,9 @@
         <code>INSTANCE_METHOD_REFERENCE</code>
       </value>
       <value>
+        <code>INSTANCE_METHOD_TEAR_OFF</code>
+      </value>
+      <value>
         <code>INSTANCE_SETTER_DECLARATION</code>
       </value>
       <value>
@@ -770,6 +773,9 @@
         <code>LOCAL_FUNCTION_REFERENCE</code>
       </value>
       <value>
+        <code>LOCAL_FUNCTION_TEAR_OFF</code>
+      </value>
+      <value>
         <code>LOCAL_VARIABLE</code>
         <p>Deprecated - no longer sent.</p>
       </value>
@@ -827,6 +833,9 @@
         <code>STATIC_METHOD_REFERENCE</code>
       </value>
       <value>
+        <code>STATIC_METHOD_TEAR_OFF</code>
+      </value>
+      <value>
         <code>STATIC_SETTER_DECLARATION</code>
       </value>
       <value>
@@ -839,6 +848,9 @@
         <code>TOP_LEVEL_FUNCTION_REFERENCE</code>
       </value>
       <value>
+        <code>TOP_LEVEL_FUNCTION_TEAR_OFF</code>
+      </value>
+      <value>
         <code>TOP_LEVEL_GETTER_DECLARATION</code>
       </value>
       <value>
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index 18e3b5a..89f0c0e 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -380,7 +380,6 @@
   Holder mainConstantHolder;
 
   /// Maps of various object types to the holders they ended up in.
-  final Map<Library, Holder> libraryMap = {};
   final Map<ClassEntity, Holder> classEntityMap = {};
   final Map<ConstantValue, Holder> constantValueMap = {};
   final Map<MemberEntity, Holder> memberEntityMap = {};
@@ -403,11 +402,6 @@
     return map[data] ?? mainHolder;
   }
 
-  /// Returns the [Holder] for [library].
-  Holder globalObjectForLibrary(Library library) {
-    return _lookup(library, library.element, libraryMap);
-  }
-
   /// Returns true if [element] is stored in the static state holder
   /// ([staticStateHolder]).  We intend to store only mutable static state
   /// there, whereas constants are stored in 'C'. Functions, accessors,
@@ -663,7 +657,7 @@
       // Sort holders by reference count within this resource.
       var sortedHolders = holders.toList(growable: false);
       sortedHolders.sort((a, b) {
-        return a.refCount(resource).compareTo(b.refCount(resource));
+        return b.refCount(resource).compareTo(a.refCount(resource));
       });
 
       // Assign names based on frequency. This will be ignored unless
@@ -734,7 +728,6 @@
           constantValueMap[constant.value] = constantHolder;
         }
         for (var library in fragment.libraries) {
-          libraryMap[library] = holder;
           for (var cls in library.classes) {
             _addClass(holder, cls);
           }
diff --git a/pkg/compiler/test/codegen/data/array_add.dart b/pkg/compiler/test/codegen/data/array_add.dart
index c0447fe..635192c 100644
--- a/pkg/compiler/test/codegen/data/array_add.dart
+++ b/pkg/compiler/test/codegen/data/array_add.dart
@@ -17,8 +17,8 @@
   return t1;
 }*/
 /*canary.member: test1:function() {
-  var t1 = B._setArrayType([], type$.JSArray_int);
-  A.JSArray_methods.add$1(t1, 1);
+  var t1 = A._setArrayType([], type$.JSArray_int);
+  B.JSArray_methods.add$1(t1, 1);
   return t1;
 }*/
 test1() {
@@ -29,7 +29,7 @@
   F.test1();
 }*/
 /*canary.member: main:function() {
-  B.test1();
+  A.test1();
 }*/
 main() {
   test1();
diff --git a/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart b/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
index e52a16a..4b47674 100644
--- a/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
+++ b/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
@@ -21,7 +21,7 @@
   return C.JSString_methods.codeUnitAt$1("Hello", 1.5);
 }*/
 /*canary.member: foo2:function() {
-  return A.JSString_methods.codeUnitAt$1("Hello", B._asInt(1.5));
+  return B.JSString_methods.codeUnitAt$1("Hello", A._asInt(1.5));
 }*/
 foo2() {
   var a = 'Hello';
@@ -35,7 +35,7 @@
   return C.JSString_methods._codeUnitAt$1("Hello", 55);
 }*/
 /*canary.member: foo3:function() {
-  return A.JSString_methods._codeUnitAt$1("Hello", 55);
+  return B.JSString_methods._codeUnitAt$1("Hello", 55);
 }*/
 foo3() {
   var a = 'Hello';
diff --git a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
index 7cdad26..b473933 100644
--- a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
+++ b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
@@ -31,7 +31,7 @@
   return J.$shru$n(thing, 1);
 }*/
 /*canary.member: cannotRecognize:function(thing) {
-  return B._asInt(J.$shru$n(thing, 1));
+  return A._asInt(J.$shru$n(thing, 1));
 }*/
 int cannotRecognize(dynamic thing) {
   return thing >>> 1;
@@ -42,7 +42,7 @@
   return C.JSInt_methods.$shru(1, -1);
 }*/
 /*canary.member: cannotConstantFold:function() {
-  return A.JSInt_methods.$shru(1, -1);
+  return B.JSInt_methods.$shru(1, -1);
 }*/
 int cannotConstantFold() {
   var a = 1;
@@ -72,7 +72,7 @@
   return C.JSInt_methods.$shru(1, a);
 }*/
 /*canary.member: unspecialized:function(a) {
-  return A.JSInt_methods.$shru(1, a);
+  return B.JSInt_methods.$shru(1, a);
 }*/
 int unspecialized(int a) {
   return 1 >>> a;
@@ -83,7 +83,7 @@
   return C.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
 }*/
 /*canary.member: otherPositive2:function(param) {
-  return A.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
+  return B.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
 }*/
 int otherPositive2(bool param) {
   var a = param ? 1 : 2;
@@ -114,7 +114,7 @@
   return C.JSInt_methods._shruOtherPositive$1(a, b);
 }*/
 /*canary.member: otherPositive6:function(a, b) {
-  return A.JSInt_methods._shruOtherPositive$1(a, b);
+  return B.JSInt_methods._shruOtherPositive$1(a, b);
 }*/
 int otherPositive6(int a, int b) {
   return a >>> b;
diff --git a/pkg/compiler/test/codegen/data/tdiv1.dart b/pkg/compiler/test/codegen/data/tdiv1.dart
index 747fe8f..9c83d58 100644
--- a/pkg/compiler/test/codegen/data/tdiv1.dart
+++ b/pkg/compiler/test/codegen/data/tdiv1.dart
@@ -49,7 +49,7 @@
   return C.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
 }*/
 /*canary.member: foo3:function(param) {
-  return A.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
+  return B.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
 }*/
 int foo3(bool param) {
   var a = param ? 0xFFFFFFFF : -1;
@@ -63,7 +63,7 @@
   return C.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
 }*/
 /*canary.member: foo4:function(param1, param2) {
-  return A.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
+  return B.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
 }*/
 int foo4(bool param1, int param2) {
   var a = param1 ? 0xFFFFFFFF : 0;
@@ -80,7 +80,7 @@
 }*/
 /*canary.member: foo5:function(param1, param2) {
   var a = param1 ? 4294967295 : 0;
-  return A.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
+  return B.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
 }*/
 int foo5(bool param1, bool param2) {
   var a = param1 ? 0xFFFFFFFF : 0;
@@ -99,7 +99,7 @@
 }*/
 /*canary.member: foo_regress_37502:function(param1, param2) {
   var a = param1 ? 1.2 : 12.3;
-  return A.JSInt_methods.gcd$1(A.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
+  return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
 }*/
 foo_regress_37502(param1, param2) {
   var a = param1 ? 1.2 : 12.3;
diff --git a/pkg/compiler/test/codegen/data_2/tdiv1.dart b/pkg/compiler/test/codegen/data_2/tdiv1.dart
index e647e4a..3c3e6b7 100644
--- a/pkg/compiler/test/codegen/data_2/tdiv1.dart
+++ b/pkg/compiler/test/codegen/data_2/tdiv1.dart
@@ -30,7 +30,7 @@
   return (param ? 4294967295 : 1) / 2 | 0;
 }*/
 /*canary.member: foo1:function(param) {
-  return (B.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
+  return (A.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
 }*/
 int foo1(bool param) {
   var a = param ? 0xFFFFFFFF : 1;
@@ -47,7 +47,7 @@
   return (param ? 4294967295 : 1) / 3 | 0;
 }*/
 /*canary.member: foo2:function(param) {
-  return (B.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
+  return (A.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
 }*/
 int foo2(bool param) {
   var a = param ? 0xFFFFFFFF : 1;
@@ -64,7 +64,7 @@
   return C.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
 }*/
 /*canary.member: foo3:function(param) {
-  return A.JSInt_methods._tdivFast$1(B.boolConversionCheck(param) ? 4294967295 : -1, 2);
+  return B.JSInt_methods._tdivFast$1(A.boolConversionCheck(param) ? 4294967295 : -1, 2);
 }*/
 int foo3(bool param) {
   var a = param ? 0xFFFFFFFF : -1;
@@ -81,7 +81,7 @@
   return C.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
 }*/
 /*canary.member: foo4:function(param1, param2) {
-  return A.JSInt_methods.$tdiv(B.boolConversionCheck(param1) ? 4294967295 : 0, param2);
+  return B.JSInt_methods.$tdiv(A.boolConversionCheck(param1) ? 4294967295 : 0, param2);
 }*/
 int foo4(bool param1, int param2) {
   var a = param1 ? 0xFFFFFFFF : 0;
@@ -101,8 +101,8 @@
   return C.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
 }*/
 /*canary.member: foo5:function(param1, param2) {
-  var a = B.boolConversionCheck(param1) ? 4294967295 : 0;
-  return A.JSInt_methods.$tdiv(a, B.boolConversionCheck(param2) ? 3 : 4);
+  var a = A.boolConversionCheck(param1) ? 4294967295 : 0;
+  return B.JSInt_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3 : 4);
 }*/
 int foo5(bool param1, bool param2) {
   var a = param1 ? 0xFFFFFFFF : 0;
@@ -124,8 +124,8 @@
   return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
 }*/
 /*canary.member: foo_regress_37502:function(param1, param2) {
-  var a = B.boolConversionCheck(param1) ? 1.2 : 12.3;
-  return A.JSInt_methods.gcd$1(A.JSNumber_methods.$tdiv(a, B.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
+  var a = A.boolConversionCheck(param1) ? 1.2 : 12.3;
+  return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
 }*/
 foo_regress_37502(param1, param2) {
   var a = param1 ? 1.2 : 12.3;
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index 15b0460..59f914c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -314,6 +314,25 @@
     return candidateType;
   }
 
+  DartType getMemberTypeForTarget(Member target) {
+    DartType candidateType = _computeMemberType(thisType, target);
+    if (!classBuilder.library.isNonNullableByDefault) {
+      DartType? legacyErasure;
+      if (target == hierarchy.coreTypes.objectEquals) {
+        // In legacy code we special case `Object.==` to infer `dynamic`
+        // instead `Object!`.
+        legacyErasure = new FunctionType([const DynamicType()],
+            hierarchy.coreTypes.boolLegacyRawType, Nullability.legacy);
+      } else {
+        legacyErasure = rawLegacyErasure(candidateType);
+      }
+      if (legacyErasure != null) {
+        candidateType = legacyErasure;
+      }
+    }
+    return candidateType;
+  }
+
   void _ensureCombinedMemberSignatureType() {
     if (!_isCombinedMemberSignatureTypeComputed) {
       _isCombinedMemberSignatureTypeComputed = true;
@@ -466,7 +485,7 @@
               member, combinedMemberSignatureType!,
               isGenericCovariantImpl: parameter.isGenericCovariantImpl,
               isCovariant: parameter.isCovariant,
-              parameterName: parameter.name,
+              parameter: parameter,
               copyLocation: copyLocation);
           break;
         case ProcedureKind.Method:
@@ -545,7 +564,7 @@
   Procedure _createSetterMemberSignature(Member member, DartType type,
       {required bool isCovariant,
       required bool isGenericCovariantImpl,
-      String? parameterName,
+      VariableDeclaration? parameter,
       required bool copyLocation}) {
     // ignore: unnecessary_null_comparison
     assert(isCovariant != null);
@@ -574,9 +593,12 @@
       new FunctionNode(null,
           returnType: const VoidType(),
           positionalParameters: [
-            new VariableDeclaration(parameterName ?? 'value',
+            new VariableDeclaration(parameter?.name ?? 'value',
                 type: type, isCovariant: isCovariant)
               ..isGenericCovariantImpl = isGenericCovariantImpl
+              ..fileOffset = copyLocation
+                  ? parameter?.fileOffset ?? fileOffset
+                  : fileOffset
           ]),
       isAbstract: true,
       fileUri: fileUri,
@@ -617,7 +639,8 @@
       DartType parameterType = functionType.positionalParameters[i];
       positionalParameters.add(new VariableDeclaration(parameter.name,
           type: parameterType, isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
+        ..fileOffset = copyLocation ? parameter.fileOffset : fileOffset);
     }
     List<VariableDeclaration> namedParameters = [];
     int namedParameterCount = function.namedParameters.length;
@@ -628,7 +651,8 @@
           type: namedType.type,
           isRequired: namedType.isRequired,
           isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
+        ..fileOffset = copyLocation ? parameter.fileOffset : fileOffset);
     } else if (namedParameterCount > 1) {
       Map<String, NamedType> namedTypes = {};
       for (NamedType namedType in functionType.namedParameters) {
@@ -641,7 +665,8 @@
             type: namedParameterType.type,
             isRequired: namedParameterType.isRequired,
             isCovariant: parameter.isCovariant)
-          ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+          ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
+          ..fileOffset = copyLocation ? parameter.fileOffset : fileOffset);
       }
     }
     return new Procedure(
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 43f0293..2ae41d0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -2,27 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "package:kernel/ast.dart"
-    show
-        Arguments,
-        Class,
-        DartType,
-        Expression,
-        FunctionNode,
-        Member,
-        Name,
-        NamedExpression,
-        Procedure,
-        ProcedureKind,
-        ProcedureStubKind,
-        ReturnStatement,
-        SuperMethodInvocation,
-        SuperPropertyGet,
-        SuperPropertySet,
-        TypeParameterType,
-        VariableGet;
+import "package:kernel/ast.dart";
 
 import 'package:kernel/transformations/flags.dart' show TransformerFlag;
+import 'package:kernel/type_algebra.dart';
+import 'package:kernel/type_environment.dart';
 
 import "../source/source_class_builder.dart";
 
@@ -183,20 +167,6 @@
       superTarget = superTarget.memberSignatureOrigin ?? superTarget;
     }
     procedure.isAbstract = false;
-    List<Expression> positionalArguments = function.positionalParameters
-        .map<Expression>((parameter) => new VariableGet(parameter))
-        .toList();
-    List<NamedExpression> namedArguments = function.namedParameters
-        .map((parameter) =>
-            new NamedExpression(parameter.name!, new VariableGet(parameter)))
-        .toList();
-    List<DartType> typeArguments = function.typeParameters
-        .map<DartType>((typeParameter) =>
-            new TypeParameterType.withDefaultNullabilityForLibrary(
-                typeParameter, enclosingClass.enclosingLibrary))
-        .toList();
-    Arguments arguments = new Arguments(positionalArguments,
-        types: typeArguments, named: namedArguments);
     Expression superCall;
     // ignore: unnecessary_null_comparison
     assert(superTarget != null,
@@ -208,6 +178,66 @@
     switch (kind) {
       case ProcedureKind.Method:
       case ProcedureKind.Operator:
+        FunctionType type = _combinedMemberSignature
+            .getMemberTypeForTarget(superTarget) as FunctionType;
+        if (type.typeParameters.isNotEmpty) {
+          type = Substitution.fromPairs(
+                  type.typeParameters,
+                  function.typeParameters
+                      .map((TypeParameter parameter) => new TypeParameterType
+                              .withDefaultNullabilityForLibrary(
+                          parameter, procedure.enclosingLibrary))
+                      .toList())
+              .substituteType(type.withoutTypeParameters) as FunctionType;
+        }
+        List<Expression> positionalArguments = new List.generate(
+            function.positionalParameters.length, (int index) {
+          VariableDeclaration parameter = function.positionalParameters[index];
+          int fileOffset = parameter.fileOffset;
+          Expression expression = new VariableGet(parameter)
+            ..fileOffset = fileOffset;
+          DartType superParameterType = type.positionalParameters[index];
+          if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
+              parameter.type,
+              superParameterType,
+              _combinedMemberSignature
+                      .classBuilder.library.isNonNullableByDefault
+                  ? SubtypeCheckMode.withNullabilities
+                  : SubtypeCheckMode.ignoringNullabilities)) {
+            expression = new AsExpression(expression, superParameterType)
+              ..fileOffset = fileOffset;
+          }
+          return expression;
+        }, growable: true);
+        List<NamedExpression> namedArguments =
+            new List.generate(function.namedParameters.length, (int index) {
+          VariableDeclaration parameter = function.namedParameters[index];
+          int fileOffset = parameter.fileOffset;
+          Expression expression = new VariableGet(parameter)
+            ..fileOffset = fileOffset;
+          DartType superParameterType = type.namedParameters
+              .singleWhere(
+                  (NamedType namedType) => namedType.name == parameter.name)
+              .type;
+          if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
+              parameter.type,
+              superParameterType,
+              _combinedMemberSignature
+                      .classBuilder.library.isNonNullableByDefault
+                  ? SubtypeCheckMode.withNullabilities
+                  : SubtypeCheckMode.ignoringNullabilities)) {
+            expression = new AsExpression(expression, superParameterType)
+              ..fileOffset = fileOffset;
+          }
+          return new NamedExpression(parameter.name!, expression);
+        }, growable: true);
+        List<DartType> typeArguments = function.typeParameters
+            .map<DartType>((typeParameter) =>
+                new TypeParameterType.withDefaultNullabilityForLibrary(
+                    typeParameter, enclosingClass.enclosingLibrary))
+            .toList();
+        Arguments arguments = new Arguments(positionalArguments,
+            types: typeArguments, named: namedArguments);
         superCall = new SuperMethodInvocation(
             name, arguments, superTarget as Procedure);
         break;
@@ -215,13 +245,29 @@
         superCall = new SuperPropertyGet(name, superTarget);
         break;
       case ProcedureKind.Setter:
-        superCall =
-            new SuperPropertySet(name, positionalArguments[0], superTarget);
+        DartType superParameterType =
+            _combinedMemberSignature.getMemberTypeForTarget(superTarget);
+        VariableDeclaration parameter = function.positionalParameters[0];
+        int fileOffset = parameter.fileOffset;
+        Expression expression = new VariableGet(parameter)
+          ..fileOffset = fileOffset;
+        if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
+            parameter.type,
+            superParameterType,
+            _combinedMemberSignature.classBuilder.library.isNonNullableByDefault
+                ? SubtypeCheckMode.withNullabilities
+                : SubtypeCheckMode.ignoringNullabilities)) {
+          expression = new AsExpression(expression, superParameterType)
+            ..fileOffset = fileOffset;
+        }
+        superCall = new SuperPropertySet(name, expression, superTarget);
         break;
       default:
         unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
     }
-    function.body = new ReturnStatement(superCall)..parent = function;
+    function.body = new ReturnStatement(superCall)
+      ..fileOffset = procedure.fileOffset
+      ..parent = function;
     procedure.transformerFlags |= TransformerFlag.superCalls;
     procedure.stubKind = isForwardingStub
         ? ProcedureStubKind.ConcreteForwardingStub
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 d76c881..80f997c 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
@@ -550,6 +550,20 @@
         isVoidAllowed: isVoidAllowed,
         isExpressionTypePrecise: preciseTypeErrorTemplate != null);
 
+    if (assignabilityResult.needsTearOff) {
+      TypedTearoff typedTearoff =
+          _tearOffCall(expression, expressionType as InterfaceType, fileOffset);
+      expression = typedTearoff.tearoff;
+      expressionType = typedTearoff.tearoffType;
+    }
+    if (assignabilityResult.implicitInstantiation != null) {
+      ExpressionInferenceResult instantiationResult =
+          _applyImplicitInstantiation(assignabilityResult.implicitInstantiation,
+              expressionType, expression);
+      expression = instantiationResult.expression;
+      expressionType = instantiationResult.inferredType;
+    }
+
     Expression result;
     switch (assignabilityResult.kind) {
       case AssignabilityKind.assignable:
@@ -563,21 +577,6 @@
           ..isForDynamic = expressionType is DynamicType
           ..fileOffset = fileOffset;
         break;
-      case AssignabilityKind.assignableTearoff:
-        result = _tearOffCall(
-                expression, expressionType as InterfaceType, fileOffset)
-            .tearoff;
-        break;
-      case AssignabilityKind.assignableTearoffCast:
-        result = new AsExpression(
-            _tearOffCall(
-                    expression, expressionType as InterfaceType, fileOffset)
-                .tearoff,
-            initialContextType)
-          ..isTypeError = true
-          ..isForNonNullableByDefault = isNonNullableByDefault
-          ..fileOffset = fileOffset;
-        break;
       case AssignabilityKind.unassignable:
         // Error: not assignable.  Perform error recovery.
         result = _wrapUnassignableExpression(
@@ -603,17 +602,6 @@
             expression.fileOffset,
             noLength);
         break;
-      case AssignabilityKind.unassignableTearoff:
-        TypedTearoff typedTearoff = _tearOffCall(
-            expression, expressionType as InterfaceType, fileOffset);
-        result = _wrapUnassignableExpression(
-            typedTearoff.tearoff,
-            typedTearoff.tearoffType,
-            contextType,
-            errorTemplate.withArguments(typedTearoff.tearoffType,
-                declaredContextType ?? contextType, isNonNullableByDefault));
-
-        break;
       case AssignabilityKind.unassignableCantTearoff:
         result = _wrapTearoffErrorExpression(
             expression, contextType, templateNullableTearoffError);
@@ -666,30 +654,6 @@
                   isNonNullableByDefault));
         }
         break;
-      case AssignabilityKind.unassignableNullabilityTearoff:
-        TypedTearoff typedTearoff = _tearOffCall(
-            expression, expressionType as InterfaceType, fileOffset);
-        if (expressionType == assignabilityResult.subtype &&
-            contextType == assignabilityResult.supertype) {
-          result = _wrapUnassignableExpression(
-              typedTearoff.tearoff,
-              typedTearoff.tearoffType,
-              contextType,
-              nullabilityErrorTemplate.withArguments(typedTearoff.tearoffType,
-                  declaredContextType ?? contextType, isNonNullableByDefault));
-        } else {
-          result = _wrapUnassignableExpression(
-              typedTearoff.tearoff,
-              typedTearoff.tearoffType,
-              contextType,
-              nullabilityPartErrorTemplate.withArguments(
-                  typedTearoff.tearoffType,
-                  declaredContextType ?? contextType,
-                  assignabilityResult.subtype!,
-                  assignabilityResult.supertype!,
-                  isNonNullableByDefault));
-        }
-        break;
       default:
         return unhandled("${assignabilityResult}", "ensureAssignable",
             fileOffset, helper!.uri);
@@ -807,7 +771,8 @@
           needsTearoff = true;
           if (isNonNullableByDefault && expressionType.isPotentiallyNullable) {
             return const AssignabilityResult(
-                AssignabilityKind.unassignableCantTearoff);
+                AssignabilityKind.unassignableCantTearoff,
+                needsTearOff: false);
           }
           expressionType =
               getGetterTypeForMemberTarget(callMember, expressionType)
@@ -815,9 +780,20 @@
         }
       }
     }
+    ImplicitInstantiation? implicitInstantiation;
+    if (library.enableConstructorTearOffsInLibrary) {
+      implicitInstantiation =
+          computeImplicitInstantiation(expressionType, contextType);
+      if (implicitInstantiation != null) {
+        expressionType = implicitInstantiation.instantiatedType;
+      }
+    }
 
     if (expressionType is VoidType && !isVoidAllowed) {
-      return const AssignabilityResult(AssignabilityKind.unassignableVoid);
+      assert(implicitInstantiation == null);
+      assert(!needsTearoff);
+      return const AssignabilityResult(AssignabilityKind.unassignableVoid,
+          needsTearOff: false);
     }
 
     IsSubtypeOf isDirectSubtypeResult = typeSchemaEnvironment
@@ -826,9 +802,9 @@
         ? isDirectSubtypeResult.isSubtypeWhenUsingNullabilities()
         : isDirectSubtypeResult.isSubtypeWhenIgnoringNullabilities();
     if (isDirectlyAssignable) {
-      return needsTearoff
-          ? const AssignabilityResult(AssignabilityKind.assignableTearoff)
-          : const AssignabilityResult(AssignabilityKind.assignable);
+      return new AssignabilityResult(AssignabilityKind.assignable,
+          needsTearOff: needsTearoff,
+          implicitInstantiation: implicitInstantiation);
     }
 
     bool isIndirectlyAssignable = isNonNullableByDefault
@@ -839,30 +815,30 @@
     if (!isIndirectlyAssignable) {
       if (isNonNullableByDefault &&
           isDirectSubtypeResult.isSubtypeWhenIgnoringNullabilities()) {
-        return needsTearoff
-            ? new AssignabilityResult.withTypes(
-                AssignabilityKind.unassignableNullabilityTearoff,
-                isDirectSubtypeResult.subtype,
-                isDirectSubtypeResult.supertype)
-            : new AssignabilityResult.withTypes(
-                AssignabilityKind.unassignableNullability,
-                isDirectSubtypeResult.subtype,
-                isDirectSubtypeResult.supertype);
+        return new AssignabilityResult.withTypes(
+            AssignabilityKind.unassignableNullability,
+            isDirectSubtypeResult.subtype,
+            isDirectSubtypeResult.supertype,
+            needsTearOff: needsTearoff,
+            implicitInstantiation: implicitInstantiation);
       } else {
-        return needsTearoff
-            ? const AssignabilityResult(AssignabilityKind.unassignableTearoff)
-            : const AssignabilityResult(AssignabilityKind.unassignable);
+        return new AssignabilityResult(AssignabilityKind.unassignable,
+            needsTearOff: needsTearoff,
+            implicitInstantiation: implicitInstantiation);
       }
     }
     if (isExpressionTypePrecise) {
       // The type of the expression is known precisely, so an implicit
       // downcast is guaranteed to fail.  Insert a compile-time error.
-      return const AssignabilityResult(AssignabilityKind.unassignablePrecise);
+      assert(implicitInstantiation == null);
+      assert(!needsTearoff);
+      return const AssignabilityResult(AssignabilityKind.unassignablePrecise,
+          needsTearOff: false);
     }
     // Insert an implicit downcast.
-    return needsTearoff
-        ? const AssignabilityResult(AssignabilityKind.assignableTearoffCast)
-        : const AssignabilityResult(AssignabilityKind.assignableCast);
+    return new AssignabilityResult(AssignabilityKind.assignableCast,
+        needsTearOff: needsTearoff,
+        implicitInstantiation: implicitInstantiation);
   }
 
   bool isNull(DartType type) {
@@ -3909,10 +3885,11 @@
     }
   }
 
-  /// Performs the type inference steps necessary to instantiate a tear-off
-  /// (if necessary).
-  ExpressionInferenceResult instantiateTearOff(
-      DartType tearoffType, DartType context, Expression expression) {
+  /// Computes the implicit instantiation from an expression of [tearOffType]
+  /// to the [context] type. Return `null` if an implicit instantiation is not
+  /// necessary or possible.
+  ImplicitInstantiation? computeImplicitInstantiation(
+      DartType tearoffType, DartType context) {
     if (tearoffType is FunctionType &&
         context is FunctionType &&
         context.typeParameters.isEmpty) {
@@ -3924,19 +3901,42 @@
         FunctionType instantiatedType = functionType.withoutTypeParameters;
         typeSchemaEnvironment.inferGenericFunctionOrType(instantiatedType,
             typeParameters, [], [], context, inferredTypes, library.library);
-        if (!isTopLevel) {
-          checkBoundsInInstantiation(
-              functionType, inferredTypes, expression.fileOffset,
-              inferred: true);
-          expression = new Instantiation(expression, inferredTypes)
-            ..fileOffset = expression.fileOffset;
-        }
         Substitution substitution =
             Substitution.fromPairs(typeParameters, inferredTypes);
         tearoffType = substitution.substituteType(instantiatedType);
+        return new ImplicitInstantiation(
+            inferredTypes, functionType, tearoffType);
       }
     }
-    return new ExpressionInferenceResult(tearoffType, expression);
+    return null;
+  }
+
+  ExpressionInferenceResult _applyImplicitInstantiation(
+      ImplicitInstantiation? implicitInstantiation,
+      DartType tearOffType,
+      Expression expression) {
+    if (implicitInstantiation != null) {
+      if (!isTopLevel) {
+        checkBoundsInInstantiation(implicitInstantiation.functionType,
+            implicitInstantiation.typeArguments, expression.fileOffset,
+            inferred: true);
+      }
+      expression =
+          new Instantiation(expression, implicitInstantiation.typeArguments)
+            ..fileOffset = expression.fileOffset;
+      tearOffType = implicitInstantiation.instantiatedType;
+    }
+    return new ExpressionInferenceResult(tearOffType, expression);
+  }
+
+  /// Performs the type inference steps necessary to instantiate a tear-off
+  /// (if necessary).
+  ExpressionInferenceResult instantiateTearOff(
+      DartType tearoffType, DartType context, Expression expression) {
+    ImplicitInstantiation? implicitInstantiation =
+        computeImplicitInstantiation(tearoffType, context);
+    return _applyImplicitInstantiation(
+        implicitInstantiation, tearoffType, expression);
   }
 
   /// True if the returned [type] has non-covariant occurrences of any of
@@ -5211,12 +5211,6 @@
   /// Assignable, but needs an implicit downcast.
   assignableCast,
 
-  /// Assignable, but needs a tearoff due to a function context.
-  assignableTearoff,
-
-  /// Assignable, but needs both a tearoff and an implicit downcast.
-  assignableTearoffCast,
-
   /// Unconditionally unassignable.
   unassignable,
 
@@ -5226,30 +5220,27 @@
   /// The right-hand side type is precise, and the downcast will fail.
   unassignablePrecise,
 
-  /// Unassignable, but needs a tearoff of "call" for better error reporting.
-  unassignableTearoff,
-
   /// Unassignable because the tear-off can't be done on the nullable receiver.
   unassignableCantTearoff,
 
   /// Unassignable only because of nullability modifiers.
   unassignableNullability,
-
-  /// Unassignable because of nullability and needs a tearoff of "call" for
-  /// better error reporting.
-  unassignableNullabilityTearoff,
 }
 
 class AssignabilityResult {
   final AssignabilityKind kind;
   final DartType? subtype; // Can be null.
   final DartType? supertype; // Can be null.
+  final bool needsTearOff;
+  final ImplicitInstantiation? implicitInstantiation;
 
-  const AssignabilityResult(this.kind)
+  const AssignabilityResult(this.kind,
+      {required this.needsTearOff, this.implicitInstantiation})
       : subtype = null,
         supertype = null;
 
-  AssignabilityResult.withTypes(this.kind, this.subtype, this.supertype);
+  AssignabilityResult.withTypes(this.kind, this.subtype, this.supertype,
+      {required this.needsTearOff, this.implicitInstantiation});
 }
 
 /// Convenient way to return both a tear-off expression and its type.
@@ -5331,3 +5322,17 @@
 // TODO(johnniwinther): Should we have a special DartType implementation for
 // this.
 final DartType noInferredType = new UnknownType();
+
+class ImplicitInstantiation {
+  /// The type arguments for the instantiation.
+  final List<DartType> typeArguments;
+
+  /// The function type before the instantiation.
+  final FunctionType functionType;
+
+  /// The function type after the instantiation.
+  final DartType instantiatedType;
+
+  ImplicitInstantiation(
+      this.typeArguments, this.functionType, this.instantiatedType);
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart b/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart
index 8650911..2a1769b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart
+++ b/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart
@@ -4,11 +4,11 @@
 
 T func<T>(T value) => value;
 var funcValue = func;
-int Function(int) f = funcValue.call; // Disallowed!
-int Function(int) g = funcValue.call<int>; // Disallowed!
+int Function(int) f = funcValue.call;
+int Function(int) g = funcValue.call<int>;
 
 test(Function f) {
-  int Function(int) g = f.call<int>; // Disallowed!
+  int Function(int) g = f.call<int>;
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.strong.expect
index edfaeac..6e425f6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.strong.expect
@@ -2,23 +2,17 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:7:33: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-// int Function(int) f = funcValue.call; // Disallowed!
-//                                 ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:11:31: Error: The static type of the explicit instantiation operand must be a generic function type but is 'Function'.
 //  - 'Function' is from 'dart:core'.
 // Try changing the operand or remove the type arguments.
-//   int Function(int) g = f.call<int>; // Disallowed!
+//   int Function(int) g = f.call<int>;
 //                               ^
 //
 import self as self;
 import "dart:core" as core;
 
 static field <T extends core::Object? = dynamic>(T%) → T% funcValue = #C1;
-static field (core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:7:33: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-int Function(int) f = funcValue.call; // Disallowed!
-                                ^" in self::funcValue.call as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+static field (core::int) → core::int f = self::funcValue.call<core::int>;
 static field (core::int) → core::int g = self::funcValue.call<core::int>;
 static method func<T extends core::Object? = dynamic>(self::func::T% value) → self::func::T%
   return value;
@@ -26,7 +20,7 @@
   (core::int) → core::int g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:11:31: Error: The static type of the explicit instantiation operand must be a generic function type but is 'Function'.
  - 'Function' is from 'dart:core'.
 Try changing the operand or remove the type arguments.
-  int Function(int) g = f.call<int>; // Disallowed!
+  int Function(int) g = f.call<int>;
                               ^";
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.weak.expect
index edfaeac..6e425f6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart.weak.expect
@@ -2,23 +2,17 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:7:33: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-// int Function(int) f = funcValue.call; // Disallowed!
-//                                 ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:11:31: Error: The static type of the explicit instantiation operand must be a generic function type but is 'Function'.
 //  - 'Function' is from 'dart:core'.
 // Try changing the operand or remove the type arguments.
-//   int Function(int) g = f.call<int>; // Disallowed!
+//   int Function(int) g = f.call<int>;
 //                               ^
 //
 import self as self;
 import "dart:core" as core;
 
 static field <T extends core::Object? = dynamic>(T%) → T% funcValue = #C1;
-static field (core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:7:33: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
-int Function(int) f = funcValue.call; // Disallowed!
-                                ^" in self::funcValue.call as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+static field (core::int) → core::int f = self::funcValue.call<core::int>;
 static field (core::int) → core::int g = self::funcValue.call<core::int>;
 static method func<T extends core::Object? = dynamic>(self::func::T% value) → self::func::T%
   return value;
@@ -26,7 +20,7 @@
   (core::int) → core::int g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/call_instantiation.dart:11:31: Error: The static type of the explicit instantiation operand must be a generic function type but is 'Function'.
  - 'Function' is from 'dart:core'.
 Try changing the operand or remove the type arguments.
-  int Function(int) g = f.call<int>; // Disallowed!
+  int Function(int) g = f.call<int>;
                               ^";
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart
index e832879f..3e55497 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart
@@ -30,7 +30,7 @@
 const q = C.redirect;
 const r = C<int>.redirect;
 
-main() {
+test() {
   var a = A.new;
   var b = A<int>.new;
   var c = A.fact;
@@ -49,4 +49,6 @@
   var p = C<int>.fact;
   var q = C.redirect;
   var r = C<int>.redirect;
-}
\ No newline at end of file
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
index f506785..107b186 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
@@ -32,7 +32,7 @@
 static const field () → self::A<core::int> p = #C4;
 static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
 static const field () → self::A<core::int> r = #C6;
-static method main() → dynamic {
+static method test() → dynamic {
   <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
   () → self::A<core::int> b = #C2;
   <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
@@ -52,12 +52,7 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
-static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::fact<core::int>();
-static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::redirect<core::int>();
+static method main() → dynamic {}
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -66,7 +61,7 @@
   #C4 = instantiation self::A::fact <core::int>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int>
-  #C7 = static-tearoff self::_#C#new#tearOff
-  #C8 = static-tearoff self::_#C#fact#tearOff
-  #C9 = static-tearoff self::_#C#redirect#tearOff
+  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
index f506785..107b186 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
@@ -32,7 +32,7 @@
 static const field () → self::A<core::int> p = #C4;
 static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
 static const field () → self::A<core::int> r = #C6;
-static method main() → dynamic {
+static method test() → dynamic {
   <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
   () → self::A<core::int> b = #C2;
   <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
@@ -52,12 +52,7 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
-static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::fact<core::int>();
-static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::redirect<core::int>();
+static method main() → dynamic {}
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -66,7 +61,7 @@
   #C4 = instantiation self::A::fact <core::int>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int>
-  #C7 = static-tearoff self::_#C#new#tearOff
-  #C8 = static-tearoff self::_#C#fact#tearOff
-  #C9 = static-tearoff self::_#C#redirect#tearOff
+  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect
index 7fa3351..091c610 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect
@@ -24,4 +24,5 @@
 const p = C<int>.fact;
 const q = C.redirect;
 const r = C<int>.redirect;
+test() {}
 main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline_modelled.expect
index 34b33d7..b58704c 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline_modelled.expect
@@ -23,5 +23,6 @@
 const q = C.redirect;
 const r = C<int>.redirect;
 main() {}
+test() {}
 typedef B<T> = A<T>;
 typedef C<T> = A<int>;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
index baeca6e..fad0d55 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
@@ -32,7 +32,7 @@
 static const field () → self::A<core::int> p = #C4;
 static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
 static const field () → self::A<core::int> r = #C6;
-static method main() → dynamic {
+static method test() → dynamic {
   <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
   () → self::A<core::int> b = #C2;
   <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
@@ -52,12 +52,7 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
-static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::fact<core::int>();
-static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::redirect<core::int>();
+static method main() → dynamic {}
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -66,7 +61,7 @@
   #C4 = instantiation self::A::fact <core::int*>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int*>
-  #C7 = static-tearoff self::_#C#new#tearOff
-  #C8 = static-tearoff self::_#C#fact#tearOff
-  #C9 = static-tearoff self::_#C#redirect#tearOff
+  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
index ddd2364..2e30650 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
@@ -25,20 +25,16 @@
 static const field () → self::A<core::int> j = self::A::fact<core::int>;
 static const field <T extends core::Object? = dynamic>() → self::A<T%> k = self::A::redirect;
 static const field () → self::A<core::int> l = self::A::redirect<core::int>;
-static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = self::_#C#new#tearOff;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = <unrelated T extends core::Object? = dynamic>.(self::A::•<core::int>);
 static const field () → self::A<core::int> n = self::A::•<core::int>;
-static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = self::_#C#fact#tearOff;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = <unrelated T extends core::Object? = dynamic>.(self::A::fact<core::int>);
 static const field () → self::A<core::int> p = self::A::fact<core::int>;
-static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = self::_#C#redirect#tearOff;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = <unrelated T extends core::Object? = dynamic>.(self::A::redirect<core::int>);
 static const field () → self::A<core::int> r = self::A::redirect<core::int>;
+static method test() → dynamic
+  ;
 static method main() → dynamic
   ;
-static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::fact<core::int>();
-static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::redirect<core::int>();
 
 
 Extra constant evaluation status:
@@ -54,10 +50,10 @@
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:23:11 -> InstantiationConstant(A.fact<int*>)
 Evaluated: RedirectingFactoryTearOff @ org-dartlang-testcase:///const_tear_off.dart:24:11 -> RedirectingFactoryTearOffConstant(A.redirect)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:25:11 -> InstantiationConstant(A.redirect<int*>)
-Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> StaticTearOffConstant(_#C#new#tearOff)
+Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> TypedefTearOffConstant(<T>A.<int>)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:27:11 -> InstantiationConstant(A.<int*>)
-Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> StaticTearOffConstant(_#C#fact#tearOff)
+Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> TypedefTearOffConstant(<T>A.fact<int>)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:29:11 -> InstantiationConstant(A.fact<int*>)
-Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> StaticTearOffConstant(_#C#redirect#tearOff)
+Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> TypedefTearOffConstant(<T>A.redirect<int>)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:31:11 -> InstantiationConstant(A.redirect<int*>)
-Extra constant evaluation: evaluated: 24, effectively constant: 18
+Extra constant evaluation: evaluated: 21, effectively constant: 18
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
index baeca6e..fad0d55 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
@@ -32,7 +32,7 @@
 static const field () → self::A<core::int> p = #C4;
 static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
 static const field () → self::A<core::int> r = #C6;
-static method main() → dynamic {
+static method test() → dynamic {
   <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
   () → self::A<core::int> b = #C2;
   <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
@@ -52,12 +52,7 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
-static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::fact<core::int>();
-static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
-  return self::A::redirect<core::int>();
+static method main() → dynamic {}
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -66,7 +61,7 @@
   #C4 = instantiation self::A::fact <core::int*>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int*>
-  #C7 = static-tearoff self::_#C#new#tearOff
-  #C8 = static-tearoff self::_#C#fact#tearOff
-  #C9 = static-tearoff self::_#C#redirect#tearOff
+  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect
index 1ecd540..ceaf4af 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect
@@ -90,20 +90,6 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
-  return core::List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
-  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
-  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
-  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
-  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
-  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
-  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -114,7 +100,4 @@
   #C6 = instantiation self::Ext|estat <core::int>
   #C7 = TypeLiteralConstant(core::List<core::int>)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int>>)
-  #C9 = null
-  #C10 = false
-  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect
index 4176e23..aa394b3 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect
@@ -98,20 +98,6 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
-  return core::_List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
-  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
-  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
-  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
-  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
-  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
-  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -122,7 +108,4 @@
   #C6 = instantiation self::Ext|estat <core::int>
   #C7 = TypeLiteralConstant(core::List<core::int>)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int>>)
-  #C9 = null
-  #C10 = false
-  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect
index 10969f4..ea4ceb1 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect
@@ -90,20 +90,6 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
-  return core::List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
-  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
-  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
-  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
-  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
-  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
-  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -114,7 +100,4 @@
   #C6 = instantiation self::Ext|estat <core::int*>
   #C7 = TypeLiteralConstant(core::List<core::int*>*)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int*>*>*)
-  #C9 = null
-  #C10 = false
-  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect
index 0db844e..6476dce 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect
@@ -57,17 +57,3 @@
   return () → void => self::Ext|emethod(#this);
 static method main() → void
   ;
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
-  return core::List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
-  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
-  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
-  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
-  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
-  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
-  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect
index f3202b5..fc6c975 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect
@@ -98,20 +98,6 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
-  return core::_List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
-  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
-  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
-  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
-  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
-  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
-static method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/array_patch.dart */ _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
-  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -122,7 +108,4 @@
   #C6 = instantiation self::Ext|estat <core::int*>
   #C7 = TypeLiteralConstant(core::List<core::int*>*)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int*>*>*)
-  #C9 = null
-  #C10 = false
-  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/folder.options b/pkg/front_end/testcases/constructor_tearoffs/folder.options
index 39d8895..73976a7 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/folder.options
+++ b/pkg/front_end/testcases/constructor_tearoffs/folder.options
@@ -1 +1,2 @@
---enable-experiment=constructor-tearoffs
\ No newline at end of file
+--enable-experiment=constructor-tearoffs
+--force-constructor-tear-off-lowering=0
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart
new file mode 100644
index 0000000..f3c1fd4
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+T id<T>(T t) => t;
+T Function<T>(T) alias = id;
+
+class Class {
+  T call<T>(T t) => t;
+}
+
+method(int Function(int) f) {}
+
+test() {
+  Class c = new Class();
+  int Function(int) f = alias;
+  int Function(int) g;
+  g = alias;
+  int Function(int) h = c;
+  g = c;
+  method(alias);
+}
+
+main() {
+  test();
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.strong.expect
new file mode 100644
index 0000000..8c5882b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.strong.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method method((core::int) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int) → core::int f = self::alias<core::int>;
+  (core::int) → core::int g;
+  g = self::alias<core::int>;
+  (core::int) → core::int h = let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  g = let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  self::method(self::alias<core::int>);
+}
+static method main() → dynamic {
+  self::test();
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c5882b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method method((core::int) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int) → core::int f = self::alias<core::int>;
+  (core::int) → core::int g;
+  g = self::alias<core::int>;
+  (core::int) → core::int h = let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  g = let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  self::method(self::alias<core::int>);
+}
+static method main() → dynamic {
+  self::test();
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..09034a5
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+T id<T>(T t) => t;
+T Function<T>(T) alias = id;
+
+class Class {
+  T call<T>(T t) => t;
+}
+
+method(int Function(int) f) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3f658da
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+T Function<T>(T) alias = id;
+T id<T>(T t) => t;
+
+class Class {
+  T call<T>(T t) => t;
+}
+
+main() {}
+method(int Function(int) f) {}
+test() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.expect
new file mode 100644
index 0000000..8c5882b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method method((core::int) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int) → core::int f = self::alias<core::int>;
+  (core::int) → core::int g;
+  g = self::alias<core::int>;
+  (core::int) → core::int h = let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  g = let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  self::method(self::alias<core::int>);
+}
+static method main() → dynamic {
+  self::test();
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.outline.expect
new file mode 100644
index 0000000..20c75c3
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  ;
+static method method((core::int) → core::int f) → dynamic
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.transformed.expect
new file mode 100644
index 0000000..8c5882b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation.dart.weak.transformed.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method method((core::int) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int) → core::int f = self::alias<core::int>;
+  (core::int) → core::int g;
+  g = self::alias<core::int>;
+  (core::int) → core::int h = let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  g = let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}<core::int>;
+  self::method(self::alias<core::int>);
+}
+static method main() → dynamic {
+  self::test();
+}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart
new file mode 100644
index 0000000..beb6855
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+T id<T>(T t, int i) => t;
+T Function<T>(T, int i)? alias = id;
+
+class Class {
+  T call<T>(T t, int i) => t;
+}
+
+method(int Function(int, int?) f) {}
+
+test() {
+  Class c = new Class();
+  int Function(int, int) f = alias;
+  int Function(int, int?)? g;
+  g = alias;
+  int Function(int, int?) h = c;
+  g = c;
+  method(alias);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect
new file mode 100644
index 0000000..e03c2e6
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+//   int Function(int, int) f = alias;
+//                              ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = alias;
+//       ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   int Function(int, int?) h = c;
+//                           ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = c;
+//   ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   method(alias);
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t, core::int i) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%, core::int) →? T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t, core::int i) → self::id::T%
+  return t;
+static method method((core::int, core::int?) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+  int Function(int, int) f = alias;
+                             ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
+  (core::int, core::int?) →? core::int g;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = alias;
+      ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+  (core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  int Function(int, int?) h = c;
+                          ^" in (let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = c;
+  ^" in (let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+  self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  method(alias);
+         ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect
new file mode 100644
index 0000000..477d480
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+//   int Function(int, int) f = alias;
+//                              ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = alias;
+//       ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   int Function(int, int?) h = c;
+//                           ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = c;
+//   ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   method(alias);
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t, core::int i) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%, core::int) →? T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t, core::int i) → self::id::T%
+  return t;
+static method method((core::int, core::int?) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+  int Function(int, int) f = alias;
+                             ^" in let (core::int, core::int) →? core::int #t1 = self::alias<core::int> in #t1 == null ?{(core::int, core::int) → core::int} #t1 as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int : #t1{(core::int, core::int) → core::int};
+  (core::int, core::int?) →? core::int g;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = alias;
+      ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+  (core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  int Function(int, int?) h = c;
+                          ^" in (let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = c;
+  ^" in (let final self::Class #t3 = c in #t3 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t3.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+  self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  method(alias);
+         ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..cb7f7b4
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+T id<T>(T t, int i) => t;
+T Function<T>(T, int i)? alias = id;
+
+class Class {
+  T call<T>(T t, int i) => t;
+}
+
+method(int Function(int, int?) f) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ecb4f22
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+T Function<T>(T, int i)? alias = id;
+T id<T>(T t, int i) => t;
+
+class Class {
+  T call<T>(T t, int i) => t;
+}
+
+main() {}
+method(int Function(int, int?) f) {}
+test() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect
new file mode 100644
index 0000000..e03c2e6
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+//   int Function(int, int) f = alias;
+//                              ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = alias;
+//       ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   int Function(int, int?) h = c;
+//                           ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = c;
+//   ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   method(alias);
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t, core::int i) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%, core::int) →? T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t, core::int i) → self::id::T%
+  return t;
+static method method((core::int, core::int?) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+  int Function(int, int) f = alias;
+                             ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
+  (core::int, core::int?) →? core::int g;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = alias;
+      ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+  (core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  int Function(int, int?) h = c;
+                          ^" in (let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = c;
+  ^" in (let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+  self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  method(alias);
+         ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.outline.expect
new file mode 100644
index 0000000..6e67eb2
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t, core::int i) → self::Class::call::T%
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%, core::int) →? T% alias;
+static method id<T extends core::Object? = dynamic>(self::id::T% t, core::int i) → self::id::T%
+  ;
+static method method((core::int, core::int?) → core::int f) → dynamic
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect
new file mode 100644
index 0000000..c7c9093
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+//   int Function(int, int) f = alias;
+//                              ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = alias;
+//       ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   int Function(int, int?) h = c;
+//                           ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+//   g = c;
+//   ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+//   method(alias);
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t, core::int i) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%, core::int) →? T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t, core::int i) → self::id::T%
+  return t;
+static method method((core::int, core::int?) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
+  int Function(int, int) f = alias;
+                             ^" in self::alias<core::int>;
+  (core::int, core::int?) →? core::int g;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = alias;
+      ^" in self::alias<core::int>;
+  (core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  int Function(int, int?) h = c;
+                          ^" in let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>;
+  g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
+  g = c;
+  ^" in let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>;
+  self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
+  method(alias);
+         ^" in self::alias<core::int>);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect
index ba4c564..ce055a4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect
@@ -49,12 +49,6 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
-static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
-  return new self::A::•<self::_#F#new#tearOff::X>();
-static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
-  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect
index 966f2f6..0f0953f 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect
@@ -49,12 +49,6 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
-static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
-  return new self::A::•<self::_#F#new#tearOff::X>();
-static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
-  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -68,4 +62,4 @@
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:32:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:34:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:35:3 -> BoolConstant(true)
-Extra constant evaluation: evaluated: 36, effectively constant: 6
+Extra constant evaluation: evaluated: 33, effectively constant: 6
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect
index 379376e..1121885 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect
@@ -49,12 +49,6 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
-static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
-  return new self::A::•<self::_#F#new#tearOff::X>();
-static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
-  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect
index 6063fc6..deb3803 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect
@@ -12,25 +12,19 @@
 static final field core::bool inSoundMode;
 static const field () → self::A<core::int> f1a = self::A::•<core::int>;
 static const field () → self::A<core::int> f1b = self::A::•<core::int>;
-static const field () → self::A<core::int> f1c = self::_#F#new#tearOff<core::int>;
+static const field () → self::A<core::int> f1c = <X extends core::num>.(self::A::•<X>)<core::int>;
 static const field () → self::A<core::int> g1a = self::A::•<core::int>;
 static const field () → self::A<core::int> g1b = self::A::•<core::int>;
-static const field () → self::A<core::int> g1c = self::_#G#new#tearOff<dynamic>;
+static const field () → self::A<core::int> g1c = <unrelated Y extends core::Object? = dynamic>.(self::A::•<core::int>)<dynamic>;
 static const field () → self::A<core::int> h1a = self::A::•<core::int>;
 static const field () → self::A<core::int> h1b = self::A::•<core::int>;
-static const field () → self::A<core::int> h1c = self::_#H#new#tearOff<core::int, dynamic>;
+static const field () → self::A<core::int> h1c = <X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>.(self::A::•<X%>)<core::int, dynamic>;
 static method main() → dynamic
   ;
 static method test<T extends core::num>() → dynamic
   ;
 static method expect(dynamic expected, dynamic actual) → dynamic
   ;
-static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
-  return new self::A::•<self::_#F#new#tearOff::X>();
-static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
-  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 
 Extra constant evaluation status:
@@ -43,4 +37,4 @@
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:21:13 -> InstantiationConstant(A.<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:22:13 -> InstantiationConstant(A.<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:23:31 -> InstantiationConstant(A.<int*>)
-Extra constant evaluation: evaluated: 12, effectively constant: 9
+Extra constant evaluation: evaluated: 9, effectively constant: 9
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect
index be2d1f5..74079d8 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect
@@ -49,12 +49,6 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
-static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
-  return new self::A::•<self::_#F#new#tearOff::X>();
-static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
-  return new self::A::•<core::int>();
-static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
-  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -68,4 +62,4 @@
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:32:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:34:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:35:3 -> BoolConstant(true)
-Extra constant evaluation: evaluated: 36, effectively constant: 6
+Extra constant evaluation: evaluated: 33, effectively constant: 6
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
index 6f4cc26..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
@@ -65,10 +65,6 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
-static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
-  return new self::A4::•<self::_#B4#new#tearOff::T>();
-static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
-  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
index 6f4cc26..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
@@ -65,10 +65,6 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
-static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
-  return new self::A4::•<self::_#B4#new#tearOff::T>();
-static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
-  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
index 6f4cc26..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
@@ -65,10 +65,6 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
-static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
-  return new self::A4::•<self::_#B4#new#tearOff::T>();
-static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
-  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect
index 13089c3..fd75da2 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect
@@ -44,7 +44,3 @@
   ;
 static method main() → dynamic
   ;
-static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
-  return new self::A4::•<self::_#B4#new#tearOff::T>();
-static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
-  return new self::A5::•<core::List<dynamic>, Never?>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
index 6f4cc26..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
@@ -65,10 +65,6 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
-static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
-  return new self::A4::•<self::_#B4#new#tearOff::T>();
-static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
-  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect
index f018785e..ba3e087 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect
@@ -80,8 +80,6 @@
                    ^^^";
 }
 static method main() → dynamic {}
-static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
-  return new self::A::•<self::_#D2#new#tearOff::X>();
 
 constants  {
   #C1 = static-tearoff self::A::foo
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect
index f018785e..ba3e087 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect
@@ -80,8 +80,6 @@
                    ^^^";
 }
 static method main() → dynamic {}
-static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
-  return new self::A::•<self::_#D2#new#tearOff::X>();
 
 constants  {
   #C1 = static-tearoff self::A::foo
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect
index 67dd644..59bdc1d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect
@@ -80,8 +80,6 @@
                    ^^^";
 }
 static method main() → dynamic {}
-static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
-  return new self::A::•<self::_#D2#new#tearOff::X>();
 
 constants  {
   #C1 = static-tearoff self::A::foo
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect
index 07e6b54..377862f 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect
@@ -14,5 +14,3 @@
   ;
 static method main() → dynamic
   ;
-static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
-  return new self::A::•<self::_#D2#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect
index 67dd644..59bdc1d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect
@@ -80,8 +80,6 @@
                    ^^^";
 }
 static method main() → dynamic {}
-static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
-  return new self::A::•<self::_#D2#new#tearOff::X>();
 
 constants  {
   #C1 = static-tearoff self::A::foo
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
index ae2f0d4..e445535 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
@@ -15,11 +15,21 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y>() test17() => DB2.new; // Error.
+//                                ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+//                                   ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -87,7 +97,10 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y>() test17() => DB2.new; // Error.
+                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
 static method test19() → () → self::B<core::num>
@@ -102,24 +115,13 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
-static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
-  return new self::A::•();
-static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
-  return new self::B::•<self::_#DB2#new#tearOff::X>();
-static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
-  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
-static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
-  return self::B::bar<self::_#DB2#bar#tearOff::X>();
-static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
-  return new self::B::•<self::_#DB3#new#tearOff::X>();
-static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
-  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
-static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
-  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -133,7 +135,7 @@
   #C9 = instantiation self::B::• <core::num>
   #C10 = instantiation self::B::foo <core::num>
   #C11 = instantiation self::B::bar <core::num>
-  #C12 = static-tearoff self::_#DB2#new#tearOff
-  #C13 = static-tearoff self::_#DB3#new#tearOff
+  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
+  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
   #C14 = instantiation self::B::• <Never>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
index ae2f0d4..ddc1a03 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
@@ -15,11 +15,21 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y>() test17() => DB2.new; // Error.
+//                                ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+//                                   ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -87,6 +97,9 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
+                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y>() test17() => DB2.new; // Error.
                                ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
@@ -102,24 +115,13 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
                                   ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
-static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
-  return new self::A::•();
-static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
-  return new self::B::•<self::_#DB2#new#tearOff::X>();
-static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
-  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
-static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
-  return self::B::bar<self::_#DB2#bar#tearOff::X>();
-static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
-  return new self::B::•<self::_#DB3#new#tearOff::X>();
-static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
-  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
-static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
-  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -133,7 +135,7 @@
   #C9 = instantiation self::B::• <core::num>
   #C10 = instantiation self::B::foo <core::num>
   #C11 = instantiation self::B::bar <core::num>
-  #C12 = static-tearoff self::_#DB2#new#tearOff
-  #C13 = static-tearoff self::_#DB3#new#tearOff
+  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
+  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
   #C14 = instantiation self::B::• <Never>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
index a1d6e2f..835e035 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
@@ -15,11 +15,21 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y>() test17() => DB2.new; // Error.
+//                                ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+//                                   ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -87,7 +97,10 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y>() test17() => DB2.new; // Error.
+                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
 static method test19() → () → self::B<core::num>
@@ -102,24 +115,13 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
-static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
-  return new self::A::•();
-static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
-  return new self::B::•<self::_#DB2#new#tearOff::X>();
-static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
-  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
-static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
-  return self::B::bar<self::_#DB2#bar#tearOff::X>();
-static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
-  return new self::B::•<self::_#DB3#new#tearOff::X>();
-static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
-  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
-static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
-  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -133,7 +135,7 @@
   #C9 = instantiation self::B::• <core::num*>
   #C10 = instantiation self::B::foo <core::num*>
   #C11 = instantiation self::B::bar <core::num*>
-  #C12 = static-tearoff self::_#DB2#new#tearOff
-  #C13 = static-tearoff self::_#DB3#new#tearOff
+  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
+  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
   #C14 = instantiation self::B::• <Never*>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect
index 7a1ba29..fda6d4f 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect
@@ -69,17 +69,3 @@
   ;
 static method main() → dynamic
   ;
-static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
-  return new self::A::•();
-static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
-  return new self::B::•<self::_#DB2#new#tearOff::X>();
-static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
-  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
-static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
-  return self::B::bar<self::_#DB2#bar#tearOff::X>();
-static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
-  return new self::B::•<self::_#DB3#new#tearOff::X>();
-static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
-  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
-static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
-  return self::B::bar<self::_#DB3#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
index a1d6e2f..f6769ba 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
@@ -15,11 +15,21 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y>() test17() => DB2.new; // Error.
+//                                ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
+// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+//                                   ^
+//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -87,6 +97,9 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
+                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y>() test17() => DB2.new; // Error.
                                ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
@@ -102,24 +115,13 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
+                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
+ - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
+B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
                                   ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
-static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
-  return new self::A::•();
-static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
-  return new self::B::•<self::_#DB2#new#tearOff::X>();
-static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
-  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
-static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
-  return self::B::bar<self::_#DB2#bar#tearOff::X>();
-static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
-  return new self::B::•<self::_#DB3#new#tearOff::X>();
-static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
-  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
-static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
-  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -133,7 +135,7 @@
   #C9 = instantiation self::B::• <core::num*>
   #C10 = instantiation self::B::foo <core::num*>
   #C11 = instantiation self::B::bar <core::num*>
-  #C12 = static-tearoff self::_#DB2#new#tearOff
-  #C13 = static-tearoff self::_#DB3#new#tearOff
+  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
+  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
   #C14 = instantiation self::B::• <Never*>
 }
diff --git a/pkg/front_end/testcases/general/implicit_instantiation.dart b/pkg/front_end/testcases/general/implicit_instantiation.dart
new file mode 100644
index 0000000..7459810
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_instantiation.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.14
+
+T id<T>(T t) => t;
+T Function<T>(T) alias = id;
+
+class Class {
+  T call<T>(T t) => t;
+}
+
+method(int Function(int) f) {}
+
+test() {
+  Class c = new Class();
+  int Function(int) f = alias;
+  int Function(int) g;
+  g = alias;
+  int Function(int) h = c;
+  g = c;
+  method(alias);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..5322012
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_instantiation.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.14
+T id<T>(T t) => t;
+T Function<T>(T) alias = id;
+
+class Class {
+  T call<T>(T t) => t;
+}
+
+method(int Function(int) f) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f608c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.14
+T Function<T>(T) alias = id;
+T id<T>(T t) => t;
+
+class Class {
+  T call<T>(T t) => t;
+}
+
+main() {}
+method(int Function(int) f) {}
+test() {}
diff --git a/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.expect b/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.expect
new file mode 100644
index 0000000..b226b4e
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:18:25: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   int Function(int) f = alias;
+//                         ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:20:7: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   g = alias;
+//       ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:21:21: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   int Function(int) h = c;
+//                     ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:22:3: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   g = c;
+//   ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:23:10: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'int Function(int)'.
+//   method(alias);
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method method((core::int) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int) → core::int f = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:18:25: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  int Function(int) f = alias;
+                        ^" in self::alias as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  (core::int) → core::int g;
+  g = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:20:7: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  g = alias;
+      ^" in self::alias as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  (core::int) → core::int h = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:21:21: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  int Function(int) h = c;
+                    ^" in (let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}) as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  g = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:22:3: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  g = c;
+  ^" in (let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}) as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  self::method(invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:23:10: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'int Function(int)'.
+  method(alias);
+         ^" in self::alias as{TypeError,ForNonNullableByDefault} (core::int) → core::int);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.outline.expect b/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.outline.expect
new file mode 100644
index 0000000..20c75c3
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    ;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  ;
+static method method((core::int) → core::int f) → dynamic
+  ;
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.transformed.expect b/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.transformed.expect
new file mode 100644
index 0000000..b226b4e
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_instantiation.dart.weak.transformed.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:18:25: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   int Function(int) f = alias;
+//                         ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:20:7: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   g = alias;
+//       ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:21:21: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   int Function(int) h = c;
+//                     ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:22:3: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+//   g = c;
+//   ^
+//
+// pkg/front_end/testcases/general/implicit_instantiation.dart:23:10: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'int Function(int)'.
+//   method(alias);
+//          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class
+    : super core::Object::•()
+    ;
+  method call<T extends core::Object? = dynamic>(self::Class::call::T% t) → self::Class::call::T%
+    return t;
+}
+static field <T extends core::Object? = dynamic>(T%) → T% alias = #C1;
+static method id<T extends core::Object? = dynamic>(self::id::T% t) → self::id::T%
+  return t;
+static method method((core::int) → core::int f) → dynamic {}
+static method test() → dynamic {
+  self::Class c = new self::Class::•();
+  (core::int) → core::int f = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:18:25: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  int Function(int) f = alias;
+                        ^" in self::alias as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  (core::int) → core::int g;
+  g = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:20:7: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  g = alias;
+      ^" in self::alias as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  (core::int) → core::int h = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:21:21: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  int Function(int) h = c;
+                    ^" in (let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}) as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  g = invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:22:3: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+  g = c;
+  ^" in (let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%) → T%}) as{TypeError,ForNonNullableByDefault} (core::int) → core::int;
+  self::method(invalid-expression "pkg/front_end/testcases/general/implicit_instantiation.dart:23:10: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'int Function(int)'.
+  method(alias);
+         ^" in self::alias as{TypeError,ForNonNullableByDefault} (core::int) → core::int);
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = static-tearoff self::id
+}
diff --git a/pkg/front_end/testcases/general/issue129167943.dart b/pkg/front_end/testcases/general/issue129167943.dart
index 5b7a3cd..73d1967 100644
--- a/pkg/front_end/testcases/general/issue129167943.dart
+++ b/pkg/front_end/testcases/general/issue129167943.dart
@@ -1,7 +1,9 @@
 // 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.
+
 // @dart=2.9
+
 abstract class A {}
 
 abstract class B {
diff --git a/pkg/front_end/testcases/general/issue46389.dart b/pkg/front_end/testcases/general/issue46389.dart
new file mode 100644
index 0000000..b1acb26
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46389.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  num foo(int n) {
+    print(n.runtimeType); // 'double'
+    return 1.1;
+  }
+
+  num bar({required int x}) {
+    print(x.runtimeType); // 'double'
+    return 1.1;
+  }
+
+  void set baz(int x) {
+    print(x.runtimeType); // 'double'
+  }
+
+  int boz = 0;
+}
+
+abstract class B<X> {
+  X foo(X x);
+  X bar({required X x});
+  void set baz(X x);
+  void set boz(X x);
+}
+
+class C extends A with B<num> {}
+
+void main() {
+  C a = C();
+  a.foo(1);
+  throws(() => a.foo(1.2));
+  a.bar(x: 1);
+  throws(() => a.bar(x: 1.2));
+  a.baz = 1;
+  throws(() => a.baz = 1.2);
+  a.boz = 1;
+  throws(() => a.boz = 1.2);
+}
+
+throws(void Function() f) {
+  try {
+    f();
+  } catch (e) {
+    print(e);
+    return;
+  }
+  throw 'Exception expected';
+}
diff --git a/pkg/front_end/testcases/general/issue46389.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue46389.dart.textual_outline.expect
new file mode 100644
index 0000000..8c1997d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46389.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A {
+  num foo(int n) {}
+  num bar({required int x}) {}
+  void set baz(int x) {}
+  int boz = 0;
+}
+
+abstract class B<X> {
+  X foo(X x);
+  X bar({required X x});
+  void set baz(X x);
+  void set boz(X x);
+}
+
+class C extends A with B<num> {}
+
+void main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue46389.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue46389.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8aae483
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46389.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+abstract class B<X> {
+  X bar({required X x});
+  X foo(X x);
+  void set baz(X x);
+  void set boz(X x);
+}
+
+class A {
+  int boz = 0;
+  num bar({required int x}) {}
+  num foo(int n) {}
+  void set baz(int x) {}
+}
+
+class C extends A with B<num> {}
+
+throws(void Function() f) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue46389.dart.weak.expect b/pkg/front_end/testcases/general/issue46389.dart.weak.expect
new file mode 100644
index 0000000..ef8ec02
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46389.dart.weak.expect
@@ -0,0 +1,73 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int boz = 0;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(core::int n) → core::num {
+    core::print(n.{core::Object::runtimeType}{core::Type});
+    return 1.1;
+  }
+  method bar({required core::int x = #C1}) → core::num {
+    core::print(x.{core::Object::runtimeType}{core::Type});
+    return 1.1;
+  }
+  set baz(core::int x) → void {
+    core::print(x.{core::Object::runtimeType}{core::Type});
+  }
+}
+abstract class B<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+  abstract method foo(generic-covariant-impl self::B::X% x) → self::B::X%;
+  abstract method bar({required generic-covariant-impl self::B::X% x = #C1}) → self::B::X%;
+  abstract set baz(generic-covariant-impl self::B::X% x) → void;
+  abstract set boz(generic-covariant-impl self::B::X% x) → void;
+}
+abstract class _C&A&B = self::A with self::B<core::num> /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub set boz(generic-covariant-impl core::num x) → void
+    return super.{self::A::boz} = x as core::int;
+  forwarding-stub method foo(generic-covariant-impl core::num x) → core::num
+    return super.{self::A::foo}(x as core::int);
+  forwarding-stub method bar({required generic-covariant-impl core::num x = #C1}) → core::num
+    return super.{self::A::bar}(x: x as core::int);
+  forwarding-stub set baz(generic-covariant-impl core::num x) → void
+    return super.{self::A::baz} = x as core::int;
+}
+class C extends self::_C&A&B {
+  synthetic constructor •() → self::C
+    : super self::_C&A&B::•()
+    ;
+}
+static method main() → void {
+  self::C a = new self::C::•();
+  a.{self::_C&A&B::foo}(1){(core::num) → core::num};
+  self::throws(() → void => a.{self::_C&A&B::foo}(1.2){(core::num) → core::num});
+  a.{self::_C&A&B::bar}(x: 1){({required x: core::num}) → core::num};
+  self::throws(() → void => a.{self::_C&A&B::bar}(x: 1.2){({required x: core::num}) → core::num});
+  a.{self::_C&A&B::baz} = 1;
+  self::throws(() → void => a.{self::_C&A&B::baz} = 1.2);
+  a.{self::_C&A&B::boz} = 1;
+  self::throws(() → void => a.{self::_C&A&B::boz} = 1.2);
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue46389.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue46389.dart.weak.outline.expect
new file mode 100644
index 0000000..c3007c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46389.dart.weak.outline.expect
@@ -0,0 +1,44 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int boz;
+  synthetic constructor •() → self::A
+    ;
+  method foo(core::int n) → core::num
+    ;
+  method bar({required core::int x}) → core::num
+    ;
+  set baz(core::int x) → void
+    ;
+}
+abstract class B<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::X%>
+    ;
+  abstract method foo(generic-covariant-impl self::B::X% x) → self::B::X%;
+  abstract method bar({required generic-covariant-impl self::B::X% x}) → self::B::X%;
+  abstract set baz(generic-covariant-impl self::B::X% x) → void;
+  abstract set boz(generic-covariant-impl self::B::X% x) → void;
+}
+abstract class _C&A&B = self::A with self::B<core::num> /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub set boz(generic-covariant-impl core::num x) → void
+    return super.{self::A::boz} = x as core::int;
+  forwarding-stub method foo(generic-covariant-impl core::num x) → core::num
+    return super.{self::A::foo}(x as core::int);
+  forwarding-stub method bar({required generic-covariant-impl core::num x}) → core::num
+    return super.{self::A::bar}(x: x as core::int);
+  forwarding-stub set baz(generic-covariant-impl core::num x) → void
+    return super.{self::A::baz} = x as core::int;
+}
+class C extends self::_C&A&B {
+  synthetic constructor •() → self::C
+    ;
+}
+static method main() → void
+  ;
+static method throws(() → void f) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue46389.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue46389.dart.weak.transformed.expect
new file mode 100644
index 0000000..cd3ad34
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46389.dart.weak.transformed.expect
@@ -0,0 +1,69 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int boz = 0;
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(core::int n) → core::num {
+    core::print(n.{core::Object::runtimeType}{core::Type});
+    return 1.1;
+  }
+  method bar({required core::int x = #C1}) → core::num {
+    core::print(x.{core::Object::runtimeType}{core::Type});
+    return 1.1;
+  }
+  set baz(core::int x) → void {
+    core::print(x.{core::Object::runtimeType}{core::Type});
+  }
+}
+abstract class B<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+  abstract method foo(generic-covariant-impl self::B::X% x) → self::B::X%;
+  abstract method bar({required generic-covariant-impl self::B::X% x = #C1}) → self::B::X%;
+  abstract set baz(generic-covariant-impl self::B::X% x) → void;
+  abstract set boz(generic-covariant-impl self::B::X% x) → void;
+}
+abstract class _C&A&B extends self::A implements self::B<core::num> /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_C&A&B
+    : super self::A::•()
+    ;
+  abstract set boz(generic-covariant-impl core::num x) → void;
+  abstract method foo(generic-covariant-impl core::num x) → core::num;
+  abstract method bar({required generic-covariant-impl core::num x = #C1}) → core::num;
+  abstract set baz(generic-covariant-impl core::num x) → void;
+}
+class C extends self::_C&A&B {
+  synthetic constructor •() → self::C
+    : super self::_C&A&B::•()
+    ;
+}
+static method main() → void {
+  self::C a = new self::C::•();
+  a.{self::_C&A&B::foo}(1){(core::num) → core::num};
+  self::throws(() → void => a.{self::_C&A&B::foo}(1.2){(core::num) → core::num});
+  a.{self::_C&A&B::bar}(x: 1){({required x: core::num}) → core::num};
+  self::throws(() → void => a.{self::_C&A&B::bar}(x: 1.2){({required x: core::num}) → core::num});
+  a.{self::_C&A&B::baz} = 1;
+  self::throws(() → void => a.{self::_C&A&B::baz} = 1.2);
+  a.{self::_C&A&B::boz} = 1;
+  self::throws(() → void => a.{self::_C&A&B::boz} = 1.2);
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue46390.dart b/pkg/front_end/testcases/general/issue46390.dart
new file mode 100644
index 0000000..305717e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46390.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  num foo(num n) {
+    print(n.runtimeType);
+    return 1.1;
+  }
+}
+
+abstract class B<X> {
+  X foo(X x);
+}
+
+class C extends A with B<num> {}
+
+void main() {
+  B<Object> b = C();
+  try {
+    b.foo(true);
+  } catch (e) {
+    print(e);
+    return;
+  }
+  throw 'Missing type error';
+}
diff --git a/pkg/front_end/testcases/general/issue46390.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue46390.dart.textual_outline.expect
new file mode 100644
index 0000000..554317f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46390.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+  num foo(num n) {}
+}
+
+abstract class B<X> {
+  X foo(X x);
+}
+
+class C extends A with B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue46390.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue46390.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77cbaa0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46390.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class B<X> {
+  X foo(X x);
+}
+
+class A {
+  num foo(num n) {}
+}
+
+class C extends A with B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue46390.dart.weak.expect b/pkg/front_end/testcases/general/issue46390.dart.weak.expect
new file mode 100644
index 0000000..88b9cff
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46390.dart.weak.expect
@@ -0,0 +1,42 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(core::num n) → core::num {
+    core::print(n.{core::Object::runtimeType}{core::Type});
+    return 1.1;
+  }
+}
+abstract class B<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+  abstract method foo(generic-covariant-impl self::B::X% x) → self::B::X%;
+}
+abstract class _C&A&B = self::A with self::B<core::num> /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub method foo(generic-covariant-impl core::num x) → core::num
+    return super.{self::A::foo}(x);
+}
+class C extends self::_C&A&B {
+  synthetic constructor •() → self::C
+    : super self::_C&A&B::•()
+    ;
+}
+static method main() → void {
+  self::B<core::Object> b = new self::C::•();
+  try {
+    b.{self::B::foo}(true){(core::Object) → core::Object};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Missing type error";
+}
diff --git a/pkg/front_end/testcases/general/issue46390.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue46390.dart.weak.outline.expect
new file mode 100644
index 0000000..9da1896
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46390.dart.weak.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method foo(core::num n) → core::num
+    ;
+}
+abstract class B<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::X%>
+    ;
+  abstract method foo(generic-covariant-impl self::B::X% x) → self::B::X%;
+}
+abstract class _C&A&B = self::A with self::B<core::num> /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_C&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub method foo(generic-covariant-impl core::num x) → core::num
+    return super.{self::A::foo}(x);
+}
+class C extends self::_C&A&B {
+  synthetic constructor •() → self::C
+    ;
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue46390.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue46390.dart.weak.transformed.expect
new file mode 100644
index 0000000..898098e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue46390.dart.weak.transformed.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(core::num n) → core::num {
+    core::print(n.{core::Object::runtimeType}{core::Type});
+    return 1.1;
+  }
+}
+abstract class B<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::X%>
+    : super core::Object::•()
+    ;
+  abstract method foo(generic-covariant-impl self::B::X% x) → self::B::X%;
+}
+abstract class _C&A&B extends self::A implements self::B<core::num> /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_C&A&B
+    : super self::A::•()
+    ;
+  abstract method foo(generic-covariant-impl core::num x) → core::num;
+}
+class C extends self::_C&A&B {
+  synthetic constructor •() → self::C
+    : super self::_C&A&B::•()
+    ;
+}
+static method main() → void {
+  self::B<core::Object> b = new self::C::•();
+  try {
+    b.{self::B::foo}(true){(core::Object) → core::Object};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Missing type error";
+}
diff --git a/pkg/front_end/testcases/general/issue47013.dart b/pkg/front_end/testcases/general/issue47013.dart
new file mode 100644
index 0000000..100055e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  void m(int n) {}
+}
+
+abstract class I {
+  void m(covariant num n);
+}
+
+class C extends A implements I {}
+
+void main() {
+  throws(() => (C() as dynamic).m(1.1));
+}
+
+throws(void Function() f) {
+  try {
+    f();
+  } catch (e) {
+    print(e);
+    return;
+  }
+  throw 'Exception expected';
+}
diff --git a/pkg/front_end/testcases/general/issue47013.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47013.dart.textual_outline.expect
new file mode 100644
index 0000000..01511eb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A {
+  void m(int n) {}
+}
+
+abstract class I {
+  void m(covariant num n);
+}
+
+class C extends A implements I {}
+
+void main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue47013.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47013.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b857bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class I {
+  void m(covariant num n);
+}
+
+class A {
+  void m(int n) {}
+}
+
+class C extends A implements I {}
+
+throws(void Function() f) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue47013.dart.weak.expect b/pkg/front_end/testcases/general/issue47013.dart.weak.expect
new file mode 100644
index 0000000..4d8fee3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(core::int n) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  abstract method m(covariant core::num n) → void;
+}
+class C extends self::A implements self::I {
+  synthetic constructor •() → self::C
+    : super self::A::•()
+    ;
+  forwarding-stub method m(covariant core::num n) → void
+    return super.{self::A::m}(n as core::int);
+}
+static method main() → void {
+  self::throws(() → void => (new self::C::•() as{ForNonNullableByDefault} dynamic){dynamic}.m(1.1));
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
diff --git a/pkg/front_end/testcases/general/issue47013.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47013.dart.weak.outline.expect
new file mode 100644
index 0000000..298bdf9
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method m(core::int n) → void
+    ;
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → self::I
+    ;
+  abstract method m(covariant core::num n) → void;
+}
+class C extends self::A implements self::I {
+  synthetic constructor •() → self::C
+    ;
+  forwarding-stub method m(covariant core::num n) → void
+    return super.{self::A::m}(n as core::int);
+}
+static method main() → void
+  ;
+static method throws(() → void f) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue47013.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47013.dart.weak.transformed.expect
new file mode 100644
index 0000000..4d8fee3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013.dart.weak.transformed.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(core::int n) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  abstract method m(covariant core::num n) → void;
+}
+class C extends self::A implements self::I {
+  synthetic constructor •() → self::C
+    : super self::A::•()
+    ;
+  forwarding-stub method m(covariant core::num n) → void
+    return super.{self::A::m}(n as core::int);
+}
+static method main() → void {
+  self::throws(() → void => (new self::C::•() as{ForNonNullableByDefault} dynamic){dynamic}.m(1.1));
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
diff --git a/pkg/front_end/testcases/general/issue47013b.dart b/pkg/front_end/testcases/general/issue47013b.dart
new file mode 100644
index 0000000..2106024
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013b.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  void m(num n) {}
+}
+
+class B extends A {
+  void m(covariant int i);
+}
+
+class C extends B {
+  void m(covariant int i) {}
+}
+
+main() {
+  A a = C();
+  throws(() => a.m(1.5));
+  a = B();
+  a.m(1.5);
+}
+
+throws(void Function() f) {
+  try {
+    f();
+  } catch (e) {
+    print(e);
+    return;
+  }
+  throw 'Exception expected';
+}
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47013b.dart.textual_outline.expect
new file mode 100644
index 0000000..4fa0be6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013b.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {
+  void m(num n) {}
+}
+
+class B extends A {
+  void m(covariant int i);
+}
+
+class C extends B {
+  void m(covariant int i) {}
+}
+
+main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47013b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4fa0be6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013b.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {
+  void m(num n) {}
+}
+
+class B extends A {
+  void m(covariant int i);
+}
+
+class C extends B {
+  void m(covariant int i) {}
+}
+
+main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.weak.expect b/pkg/front_end/testcases/general/issue47013b.dart.weak.expect
new file mode 100644
index 0000000..752be53
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013b.dart.weak.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(core::num n) → void {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  forwarding-stub forwarding-semi-stub method m(covariant core::int i) → void
+    return super.{self::A::m}(i);
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+  method m(covariant core::int i) → void {}
+}
+static method main() → dynamic {
+  self::A a = new self::C::•();
+  self::throws(() → void => a.{self::A::m}(1.5){(core::num) → void});
+  a = new self::B::•();
+  a.{self::A::m}(1.5){(core::num) → void};
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect
new file mode 100644
index 0000000..917981e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect
@@ -0,0 +1,26 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method m(core::num n) → void
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  forwarding-stub forwarding-semi-stub method m(covariant core::int i) → void
+    return super.{self::A::m}(i);
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    ;
+  method m(covariant core::int i) → void
+    ;
+}
+static method main() → dynamic
+  ;
+static method throws(() → void f) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect
new file mode 100644
index 0000000..752be53
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(core::num n) → void {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  forwarding-stub forwarding-semi-stub method m(covariant core::int i) → void
+    return super.{self::A::m}(i);
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+  method m(covariant core::int i) → void {}
+}
+static method main() → dynamic {
+  self::A a = new self::C::•();
+  self::throws(() → void => a.{self::A::m}(1.5){(core::num) → void});
+  a = new self::B::•();
+  a.{self::A::m}(1.5){(core::num) → void};
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
diff --git a/pkg/front_end/testcases/general/issue47013c.dart b/pkg/front_end/testcases/general/issue47013c.dart
new file mode 100644
index 0000000..89b8818
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013c.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class D1 {}
+
+class D2 {}
+
+class D implements D1, D2 {}
+
+class A {
+  void m(covariant D d) {}
+}
+
+abstract class B1 {
+  void m(D1 d1);
+}
+
+abstract class B2 {
+  void m(D2 d2);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47013c.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47013c.dart.textual_outline.expect
new file mode 100644
index 0000000..e66a813
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013c.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class D1 {}
+
+class D2 {}
+
+class D implements D1, D2 {}
+
+class A {
+  void m(covariant D d) {}
+}
+
+abstract class B1 {
+  void m(D1 d1);
+}
+
+abstract class B2 {
+  void m(D2 d2);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47013c.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47013c.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8652263
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013c.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+abstract class B1 {
+  void m(D1 d1);
+}
+
+abstract class B2 {
+  void m(D2 d2);
+}
+
+class A {
+  void m(covariant D d) {}
+}
+
+class D implements D1, D2 {}
+
+class D1 {}
+
+class D2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47013c.dart.weak.expect b/pkg/front_end/testcases/general/issue47013c.dart.weak.expect
new file mode 100644
index 0000000..4b15292
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013c.dart.weak.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::D1, self::D2 {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(covariant self::D d) → void {}
+}
+abstract class B1 extends core::Object {
+  synthetic constructor •() → self::B1
+    : super core::Object::•()
+    ;
+  abstract method m(self::D1 d1) → void;
+}
+abstract class B2 extends core::Object {
+  synthetic constructor •() → self::B2
+    : super core::Object::•()
+    ;
+  abstract method m(self::D2 d2) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue47013c.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47013c.dart.weak.outline.expect
new file mode 100644
index 0000000..52f2d87
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013c.dart.weak.outline.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    ;
+}
+class D extends core::Object implements self::D1, self::D2 {
+  synthetic constructor •() → self::D
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method m(covariant self::D d) → void
+    ;
+}
+abstract class B1 extends core::Object {
+  synthetic constructor •() → self::B1
+    ;
+  abstract method m(self::D1 d1) → void;
+}
+abstract class B2 extends core::Object {
+  synthetic constructor •() → self::B2
+    ;
+  abstract method m(self::D2 d2) → void;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue47013c.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47013c.dart.weak.transformed.expect
new file mode 100644
index 0000000..4b15292
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013c.dart.weak.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::D1, self::D2 {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(covariant self::D d) → void {}
+}
+abstract class B1 extends core::Object {
+  synthetic constructor •() → self::B1
+    : super core::Object::•()
+    ;
+  abstract method m(self::D1 d1) → void;
+}
+abstract class B2 extends core::Object {
+  synthetic constructor •() → self::B2
+    : super core::Object::•()
+    ;
+  abstract method m(self::D2 d2) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue47013d.dart b/pkg/front_end/testcases/general/issue47013d.dart
new file mode 100644
index 0000000..dd8a651
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013d.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+  void m(num n, int i) {}
+}
+
+class B extends A {
+  void m(covariant int i, covariant num n);
+}
+
+main() {
+  B b = B();
+  throws(() => b.m(1.5, 0));
+  A a = b;
+  throws(() => a.m(1, 1.5));
+}
+
+throws(void Function() f) {
+  try {
+    f();
+  } catch (e) {
+    print(e);
+    return;
+  }
+  throw 'Exception expected';
+}
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47013d.dart.textual_outline.expect
new file mode 100644
index 0000000..737e999
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013d.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+  void m(num n, int i) {}
+}
+
+class B extends A {
+  void m(covariant int i, covariant num n);
+}
+
+main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47013d.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..737e999
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013d.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A {
+  void m(num n, int i) {}
+}
+
+class B extends A {
+  void m(covariant int i, covariant num n);
+}
+
+main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.weak.expect b/pkg/front_end/testcases/general/issue47013d.dart.weak.expect
new file mode 100644
index 0000000..41c3ad9
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013d.dart.weak.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue47013d.dart:15:20: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+//   throws(() => b.m(1.5, 0));
+//                    ^
+//
+// pkg/front_end/testcases/general/issue47013d.dart:17:23: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+//   throws(() => a.m(1, 1.5));
+//                       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(core::num n, core::int i) → void {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  forwarding-stub forwarding-semi-stub method m(covariant core::int i, covariant core::num n) → void
+    return super.{self::A::m}(i, n as core::int);
+}
+static method main() → dynamic {
+  self::B b = new self::B::•();
+  self::throws(() → void => b.{self::B::m}(invalid-expression "pkg/front_end/testcases/general/issue47013d.dart:15:20: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+  throws(() => b.m(1.5, 0));
+                   ^" in 1.5 as{TypeError,ForNonNullableByDefault} core::int, 0){(core::int, core::num) → void});
+  self::A a = b;
+  self::throws(() → void => a.{self::A::m}(1, invalid-expression "pkg/front_end/testcases/general/issue47013d.dart:17:23: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+  throws(() => a.m(1, 1.5));
+                      ^" in 1.5 as{TypeError,ForNonNullableByDefault} core::int){(core::num, core::int) → void});
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect
new file mode 100644
index 0000000..acbd871
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method m(core::num n, core::int i) → void
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  forwarding-stub forwarding-semi-stub method m(covariant core::int i, covariant core::num n) → void
+    return super.{self::A::m}(i, n as core::int);
+}
+static method main() → dynamic
+  ;
+static method throws(() → void f) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect
new file mode 100644
index 0000000..41c3ad9
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue47013d.dart:15:20: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+//   throws(() => b.m(1.5, 0));
+//                    ^
+//
+// pkg/front_end/testcases/general/issue47013d.dart:17:23: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+//   throws(() => a.m(1, 1.5));
+//                       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method m(core::num n, core::int i) → void {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  forwarding-stub forwarding-semi-stub method m(covariant core::int i, covariant core::num n) → void
+    return super.{self::A::m}(i, n as core::int);
+}
+static method main() → dynamic {
+  self::B b = new self::B::•();
+  self::throws(() → void => b.{self::B::m}(invalid-expression "pkg/front_end/testcases/general/issue47013d.dart:15:20: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+  throws(() => b.m(1.5, 0));
+                   ^" in 1.5 as{TypeError,ForNonNullableByDefault} core::int, 0){(core::int, core::num) → void});
+  self::A a = b;
+  self::throws(() → void => a.{self::A::m}(1, invalid-expression "pkg/front_end/testcases/general/issue47013d.dart:17:23: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+  throws(() => a.m(1, 1.5));
+                      ^" in 1.5 as{TypeError,ForNonNullableByDefault} core::int){(core::num, core::int) → void});
+}
+static method throws(() → void f) → dynamic {
+  try {
+    f(){() → void};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print(e);
+    return;
+  }
+  throw "Exception expected";
+}
diff --git a/pkg/front_end/testcases/general/issue47072.dart b/pkg/front_end/testcases/general/issue47072.dart
new file mode 100644
index 0000000..1875508
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47072.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {}
+
+class B extends A {}
+
+class C {
+  // The parameter `b` is not covariant-by-declaration as seen from here.
+  void f(B b) {}
+}
+
+abstract class I {
+  // If `I` is a superinterface of any class,
+  // the parameter of its `f` is covariant-by-declaration.
+  void f(covariant A a);
+}
+
+class D extends C implements I {} // OK.
+
+void main() {
+  I i = D();
+  try {
+    i.f(A()); // Dynamic type error.
+  } catch (_) {
+    return;
+  }
+  throw 'Missing type error';
+}
diff --git a/pkg/front_end/testcases/general/issue47072.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47072.dart.textual_outline.expect
new file mode 100644
index 0000000..1762d4d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47072.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(B b) {}
+}
+
+abstract class I {
+  void f(covariant A a);
+}
+
+class D extends C implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue47072.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47072.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a509637
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47072.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class I {
+  void f(covariant A a);
+}
+
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(B b) {}
+}
+
+class D extends C implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue47072.dart.weak.expect b/pkg/front_end/testcases/general/issue47072.dart.weak.expect
new file mode 100644
index 0000000..c261fd0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47072.dart.weak.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+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 core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method f(self::B b) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  abstract method f(covariant self::A a) → void;
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+  forwarding-stub method f(covariant self::A a) → void
+    return super.{self::C::f}(a as self::B);
+}
+static method main() → void {
+  self::I i = new self::D::•();
+  try {
+    i.{self::I::f}(new self::A::•()){(self::A) → void};
+  }
+  on core::Object catch(final core::Object _) {
+    return;
+  }
+  throw "Missing type error";
+}
diff --git a/pkg/front_end/testcases/general/issue47072.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47072.dart.weak.outline.expect
new file mode 100644
index 0000000..6cd4faf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47072.dart.weak.outline.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+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 core::Object {
+  synthetic constructor •() → self::C
+    ;
+  method f(self::B b) → void
+    ;
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → self::I
+    ;
+  abstract method f(covariant self::A a) → void;
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → self::D
+    ;
+  forwarding-stub method f(covariant self::A a) → void
+    return super.{self::C::f}(a as self::B);
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/general/issue47072.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47072.dart.weak.transformed.expect
new file mode 100644
index 0000000..c261fd0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47072.dart.weak.transformed.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+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 core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method f(self::B b) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  abstract method f(covariant self::A a) → void;
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+  forwarding-stub method f(covariant self::A a) → void
+    return super.{self::C::f}(a as self::B);
+}
+static method main() → void {
+  self::I i = new self::D::•();
+  try {
+    i.{self::I::f}(new self::A::•()){(self::A) → void};
+  }
+  on core::Object catch(final core::Object _) {
+    return;
+  }
+  throw "Missing type error";
+}
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.weak.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.weak.expect
index 017b651..031bf41 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.weak.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.weak.expect
@@ -109,7 +109,7 @@
     ;
   method foo8<generic-covariant-impl Q extends self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void {}
   forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
-    return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
+    return super.{self::G::foo7}<self::H::foo7::Q*>(a, b as core::int*, c);
 }
 static field core::List<core::Iterable<dynamic>*>* globalVar;
 static method foo1(dynamic x) → dynamic {
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.weak.outline.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.weak.outline.expect
index 679e7c3..042641e 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.weak.outline.expect
@@ -89,7 +89,7 @@
   method foo8<generic-covariant-impl Q extends self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void
     ;
   forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
-    return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
+    return super.{self::G::foo7}<self::H::foo7::Q*>(a, b as core::int*, c);
 }
 static field core::List<core::Iterable<dynamic>*>* globalVar;
 static method foo1(dynamic x) → dynamic
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.weak.transformed.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.weak.transformed.expect
index ace3959..11d9dea 100644
--- a/pkg/front_end/testcases/general/vm_type_ops.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.weak.transformed.expect
@@ -109,7 +109,7 @@
     ;
   method foo8<generic-covariant-impl Q extends self::H::T*>(self::H::foo8::Q* a, covariant core::int* b, generic-covariant-impl self::H::T* c) → void {}
   forwarding-stub method foo7<generic-covariant-impl Q extends self::H::T*>(self::H::foo7::Q* a, covariant core::num* b, generic-covariant-impl self::H::T* c) → void
-    return super.{self::G::foo7}<self::H::foo7::Q*>(a, b, c);
+    return super.{self::G::foo7}<self::H::foo7::Q*>(a, b as core::int*, c);
 }
 static field core::List<core::Iterable<dynamic>*>* globalVar;
 static method foo1(dynamic x) → dynamic {
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect
index fe7b938..c1f6edc 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect
@@ -133,7 +133,7 @@
     return super.{self::Super::field1} = #externalFieldValue;
   abstract get field2() → core::String;
   forwarding-stub forwarding-semi-stub set field2(covariant core::String #externalFieldValue) → void
-    return super.{self::Super::field2} = #externalFieldValue;
+    return super.{self::Super::field2} = #externalFieldValue as core::num;
   abstract get field3() → core::int;
   abstract set field3(core::int #externalFieldValue) → void;
   abstract get field4() → core::int;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect
index e668a41..f0a2a73 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect
@@ -130,7 +130,7 @@
     return super.{self::Super::field1} = #externalFieldValue;
   abstract get field2() → core::String;
   forwarding-stub forwarding-semi-stub set field2(covariant core::String #externalFieldValue) → void
-    return super.{self::Super::field2} = #externalFieldValue;
+    return super.{self::Super::field2} = #externalFieldValue as core::num;
   abstract get field3() → core::int;
   abstract set field3(core::int #externalFieldValue) → void;
   abstract get field4() → core::int;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect
index e46c242..3588a5b 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect
@@ -66,7 +66,7 @@
   forwarding-stub forwarding-semi-stub method method1(covariant core::int i) → void
     return super.{self::Super::method1}(i);
   forwarding-stub forwarding-semi-stub method method2(covariant core::String i) → void
-    return super.{self::Super::method2}(i);
+    return super.{self::Super::method2}(i as core::num);
   abstract method method3(core::int i) → void;
   abstract method method4(covariant core::int i) → void;
   abstract method method5(covariant core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect
index 4b37dd3..8e6faa3 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect
@@ -72,7 +72,7 @@
   forwarding-stub forwarding-semi-stub method method1(covariant core::int i) → void
     return super.{self::Super::method1}(i);
   forwarding-stub forwarding-semi-stub method method2(covariant core::String i) → void
-    return super.{self::Super::method2}(i);
+    return super.{self::Super::method2}(i as core::num);
   abstract method method3(core::int i) → void;
   abstract method method4(covariant core::int i) → void;
   abstract method method5(covariant core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect
index a95406c..897ac2d 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect
@@ -66,7 +66,7 @@
   forwarding-stub forwarding-semi-stub set setter1(covariant core::int i) → void
     return super.{self::Super::setter1} = i;
   forwarding-stub forwarding-semi-stub set setter2(covariant core::String i) → void
-    return super.{self::Super::setter2} = i;
+    return super.{self::Super::setter2} = i as core::num;
   abstract set setter3(core::int i) → void;
   abstract set setter4(covariant core::int i) → void;
   abstract set setter5(covariant core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect
index af837e6..7431f4c 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect
@@ -72,7 +72,7 @@
   forwarding-stub forwarding-semi-stub set setter1(covariant core::int i) → void
     return super.{self::Super::setter1} = i;
   forwarding-stub forwarding-semi-stub set setter2(covariant core::String i) → void
-    return super.{self::Super::setter2} = i;
+    return super.{self::Super::setter2} = i as core::num;
   abstract set setter3(core::int i) → void;
   abstract set setter4(covariant core::int i) → void;
   abstract set setter5(covariant core::num n) → void;
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.expect
index ef3d7b6..0010a96 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.expect
@@ -52,6 +52,6 @@
     : super self::C::•()
     ;
   forwarding-stub set x(covariant core::num* value) → void
-    return super.{self::C::x} = value;
+    return super.{self::C::x} = value as core::int*;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.outline.expect
index 4b93548..9728f52 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.outline.expect
@@ -49,7 +49,7 @@
   synthetic constructor •() → self::D*
     ;
   forwarding-stub set x(covariant core::num* value) → void
-    return super.{self::C::x} = value;
+    return super.{self::C::x} = value as core::int*;
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.transformed.expect
index ef3d7b6..0010a96 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.weak.transformed.expect
@@ -52,6 +52,6 @@
     : super self::C::•()
     ;
   forwarding-stub set x(covariant core::num* value) → void
-    return super.{self::C::x} = value;
+    return super.{self::C::x} = value as core::int*;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.expect
index 2dac682..ee57271 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.expect
@@ -42,7 +42,7 @@
     : super self::B::•()
     ;
   forwarding-stub method f(covariant core::Object* x) → core::int*
-    return super.{self::B::f}(x);
+    return super.{self::B::f}(x as core::int*);
 }
 static method expectTypeError(() →* void callback) → void {
   try {
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.outline.expect
index 99e0d16..91e1f95 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.outline.expect
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::C*
     ;
   forwarding-stub method f(covariant core::Object* x) → core::int*
-    return super.{self::B::f}(x);
+    return super.{self::B::f}(x as core::int*);
 }
 static method expectTypeError(() →* void callback) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.transformed.expect
index 2dac682..ee57271 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.weak.transformed.expect
@@ -42,7 +42,7 @@
     : super self::B::•()
     ;
   forwarding-stub method f(covariant core::Object* x) → core::int*
-    return super.{self::B::f}(x);
+    return super.{self::B::f}(x as core::int*);
 }
 static method expectTypeError(() →* void callback) → void {
   try {
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.expect
index 4dc5053..73153a3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.expect
@@ -39,6 +39,6 @@
     : super self::B::•()
     ;
   forwarding-stub method f(generic-covariant-impl core::int* x, core::Object* y) → void
-    return super.{self::B::f}(x, y);
+    return super.{self::B::f}(x, y as core::int*);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.outline.expect
index d61d15b..5f74e13 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.outline.expect
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::C*
     ;
   forwarding-stub method f(generic-covariant-impl core::int* x, core::Object* y) → void
-    return super.{self::B::f}(x, y);
+    return super.{self::B::f}(x, y as core::int*);
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.transformed.expect
index 4dc5053..73153a3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.weak.transformed.expect
@@ -39,6 +39,6 @@
     : super self::B::•()
     ;
   forwarding-stub method f(generic-covariant-impl core::int* x, core::Object* y) → void
-    return super.{self::B::f}(x, y);
+    return super.{self::B::f}(x, y as core::int*);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.expect
index 916ff08..f5af9c6 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.expect
@@ -39,6 +39,6 @@
     : super self::B::•()
     ;
   forwarding-stub method f(covariant core::int* x, core::Object* y) → void
-    return super.{self::B::f}(x, y);
+    return super.{self::B::f}(x, y as core::int*);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.outline.expect
index e502022..7ff4383 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.outline.expect
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::C*
     ;
   forwarding-stub method f(covariant core::int* x, core::Object* y) → void
-    return super.{self::B::f}(x, y);
+    return super.{self::B::f}(x, y as core::int*);
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.transformed.expect
index 916ff08..f5af9c6 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.weak.transformed.expect
@@ -39,6 +39,6 @@
     : super self::B::•()
     ;
   forwarding-stub method f(covariant core::int* x, core::Object* y) → void
-    return super.{self::B::f}(x, y);
+    return super.{self::B::f}(x, y as core::int*);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 9093936..81489e3 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -84,6 +84,8 @@
 general/issue41210b/issue41210.no_link: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
 general/issue44733: TypeCheckError
+general/issue46389: RuntimeError # issue 46389
+general/issue46390: RuntimeError # issue 46390
 general/issue_46886: RuntimeError
 general/micro: RuntimeError
 general/mixin_application_override: TypeCheckError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 6af034c..1057daf 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -88,6 +88,8 @@
 general/issue41210b/issue41210.no_link: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
 general/issue44733: TypeCheckError
+general/issue46389: RuntimeError # issue 46389
+general/issue46390: RuntimeError # issue 46390
 general/issue_46886: RuntimeError
 general/micro: RuntimeError
 general/mixin_application_override: ExpectationFileMismatch # Too many errors.
diff --git a/pkg/front_end/tool/ast_model.dart b/pkg/front_end/tool/ast_model.dart
index 2e4d7f2..00fc28c 100644
--- a/pkg/front_end/tool/ast_model.dart
+++ b/pkg/front_end/tool/ast_model.dart
@@ -2,17 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart';
 import 'package:front_end/src/api_prototype/front_end.dart';
-import 'package:front_end/src/api_prototype/kernel_generator.dart';
-import 'package:front_end/src/api_prototype/terminal_color_support.dart';
 import 'package:front_end/src/api_unstable/ddc.dart';
 import 'package:front_end/src/compute_platform_binaries_location.dart';
 import 'package:front_end/src/fasta/kernel/kernel_api.dart';
 import 'package:front_end/src/kernel_generator_impl.dart';
 import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/core_types.dart';
 import 'package:kernel/src/printer.dart';
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/type_environment.dart';
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 92316dc..2c00251 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -26,8 +26,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
     show Utf8BytesScanner;
 
-import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 import 'package:front_end/src/api_prototype/file_system.dart';
 import 'package:front_end/src/api_prototype/memory_file_system.dart';
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index c8da9c7..a95b5d3 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -9980,6 +9980,7 @@
   bool get isConst => flags & FlagConst != 0;
 
   /// Whether the parameter is declared with the `covariant` keyword.
+  // TODO(johnniwinther): Rename to isCovariantByDeclaration
   bool get isCovariant => flags & FlagCovariant != 0;
 
   /// Whether the variable is declared as a field formal parameter of
@@ -9993,6 +9994,7 @@
   ///
   /// When `true`, runtime checks may need to be performed; see
   /// [DispatchCategory] for details.
+  // TODO(johnniwinther): Rename to isCovariantByClass
   bool get isGenericCovariantImpl => flags & FlagGenericCovariantImpl != 0;
 
   /// Whether the variable is declared with the `late` keyword.
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index c6e2222..303c0b6 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -2,13 +2,13 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+complex_reload_test: Skip # http://dartbug.com/47130
 valid_source_locations_test: Pass, Slow
 
 [ $compiler == app_jitk ]
 add_breakpoint_rpc_kernel_test: SkipByDesign # No incremental compiler available.
 async_generator_breakpoint_test: SkipByDesign # No incremental compiler available.
 break_on_activation_test: SkipByDesign # No incremental compiler available.
-complex_reload_test: RuntimeError
 debugger_inspect_test: SkipByDesign # No incremental compiler available.
 debugger_location_second_test: SkipByDesign # No script sources available.
 eval_internal_class_test: SkipByDesign # No incremental compiler available.
@@ -210,9 +210,6 @@
 [ $arch == ia32 && $compiler == dartk ]
 valid_source_locations_test: Skip # Issue 34736, too slow.
 
-[ $arch != simarm && $arch != simarm64 && $arch != simarm64c && $compiler == dartk ]
-complex_reload_test: RuntimeError
-
 [ $compiler == app_jitk && $system == linux ]
 get_vm_timeline_rpc_test: Skip # Timeout.
 
@@ -278,7 +275,6 @@
 bad_reload_test: Skip # Times out on sim architectures, also RuntimeError.
 break_on_activation_test: RuntimeError # Issue #34736
 breakpoint_in_package_parts_class_file_uri_test: RuntimeError # Issue #34736
-complex_reload_test: Skip # Times out on sim architectures, also RuntimeError.
 dds_log_history_size_gigantic_test: SkipSlow # Involves hundreds of thousands of log messages
 debugger_inspect_test: RuntimeError, Timeout # Issue #34736
 eval_internal_class_test: RuntimeError # Issue #34736
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 83eb2d1..16a8edc 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -2,13 +2,13 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+complex_reload_test: Skip # http://dartbug.com/47130
 valid_source_locations_test: Pass, Slow
 
 [ $compiler == app_jitk ]
 add_breakpoint_rpc_kernel_test: SkipByDesign # No incremental compiler available.
 async_generator_breakpoint_test: SkipByDesign # No incremental compiler available.
 break_on_activation_test: SkipByDesign # No incremental compiler available.
-complex_reload_test: RuntimeError
 debugger_inspect_test: SkipByDesign # No incremental compiler available.
 debugger_location_second_test: SkipByDesign # No script sources available.
 eval_internal_class_test: SkipByDesign # No incremental compiler available.
@@ -210,9 +210,6 @@
 [ $arch == ia32 && $compiler == dartk ]
 valid_source_locations_test: Skip # Issue 34736, too slow.
 
-[ $arch != simarm && $arch != simarm64 && $arch != simarm64c && $compiler == dartk ]
-complex_reload_test: RuntimeError
-
 [ $compiler == app_jitk && $system == linux ]
 get_vm_timeline_rpc_test: Skip # Timeout.
 
@@ -278,7 +275,6 @@
 bad_reload_test: Skip # Times out on sim architectures, also RuntimeError.
 break_on_activation_test: RuntimeError # Issue #34736
 breakpoint_in_package_parts_class_file_uri_test: RuntimeError # Issue #34736
-complex_reload_test: Skip # Times out on sim architectures, also RuntimeError.
 dds_log_history_size_gigantic_test: SkipSlow # Involves hundreds of thousands of log messages
 debugger_inspect_test: RuntimeError, Timeout # Issue #34736
 eval_internal_class_test: RuntimeError # Issue #34736
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index ec5c09d..6cd7640 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -552,7 +552,7 @@
 
       // With the nnbd experiment enabled, these non-nullable type arguments may
       // not be retained, although they will be used and expected to be
-      // canonical.
+      // canonical by Dart_NewListOfType.
       AddTypeArguments(
           TypeArguments::Handle(Z, IG->object_store()->type_argument_int()));
       AddTypeArguments(
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index df3c817..66a1480 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1148,12 +1148,12 @@
 #if !defined(DART_COMPRESSED_POINTERS)
   // Convert double value to signed 64-bit int in R0 and back to a
   // double value in V1.
-  __ fcvtzdsx(R0, V0);
+  __ fcvtzsxd(R0, V0);
   __ scvtfdx(V1, R0);
 #else
   // Convert double value to signed 32-bit int in R0 and back to a
   // double value in V1.
-  __ fcvtzdsw(R0, V0);
+  __ fcvtzswd(R0, V0);
   __ scvtfdw(V1, R0);
 #endif
 
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index ff4af61..4f214f7 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1331,17 +1331,41 @@
     const Register crn = ConcreteRegister(rn);
     EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn, kFourBytes);
   }
-  void fcvtzdsx(Register rd, VRegister vn) {
+  void fcvtzsxd(Register rd, VRegister vn) {
     ASSERT(rd != R31);
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
-    EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn));
+    EmitFPIntCvtOp(FCVTZS_D, crd, static_cast<Register>(vn));
   }
-  void fcvtzdsw(Register rd, VRegister vn) {
+  void fcvtzswd(Register rd, VRegister vn) {
     ASSERT(rd != R31);
     ASSERT(rd != CSP);
     const Register crd = ConcreteRegister(rd);
-    EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn), kFourBytes);
+    EmitFPIntCvtOp(FCVTZS_D, crd, static_cast<Register>(vn), kFourBytes);
+  }
+  void fcvtmsxd(Register rd, VRegister vn) {
+    ASSERT(rd != R31);
+    ASSERT(rd != CSP);
+    const Register crd = ConcreteRegister(rd);
+    EmitFPIntCvtOp(FCVTMS_D, crd, static_cast<Register>(vn));
+  }
+  void fcvtmswd(Register rd, VRegister vn) {
+    ASSERT(rd != R31);
+    ASSERT(rd != CSP);
+    const Register crd = ConcreteRegister(rd);
+    EmitFPIntCvtOp(FCVTMS_D, crd, static_cast<Register>(vn), kFourBytes);
+  }
+  void fcvtpsxd(Register rd, VRegister vn) {
+    ASSERT(rd != R31);
+    ASSERT(rd != CSP);
+    const Register crd = ConcreteRegister(rd);
+    EmitFPIntCvtOp(FCVTPS_D, crd, static_cast<Register>(vn));
+  }
+  void fcvtpswd(Register rd, VRegister vn) {
+    ASSERT(rd != R31);
+    ASSERT(rd != CSP);
+    const Register crd = ConcreteRegister(rd);
+    EmitFPIntCvtOp(FCVTPS_D, crd, static_cast<Register>(vn), kFourBytes);
   }
   void fmovdd(VRegister vd, VRegister vn) { EmitFPOneSourceOp(FMOVDD, vd, vn); }
   void fabsd(VRegister vd, VRegister vn) { EmitFPOneSourceOp(FABSD, vd, vn); }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index 03f8341..a54fe57 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -3161,69 +3161,206 @@
   EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(DoubleReturn, test->entry()));
 }
 
-ASSEMBLER_TEST_GENERATE(Fcvtzdsx, assembler) {
-  __ LoadDImmediate(V0, 42.0);
-  __ fcvtzdsx(R0, V0);
+ASSEMBLER_TEST_GENERATE(Fcvtzsxd, assembler) {
+  __ LoadDImmediate(V0, 42.5);
+  __ fcvtzsxd(R0, V0);
   __ ret();
 }
 
-ASSEMBLER_TEST_RUN(Fcvtzdsx, test) {
+ASSEMBLER_TEST_RUN(Fcvtzsxd, test) {
   typedef int64_t (*Int64Return)() DART_UNUSED;
   EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
 }
 
-ASSEMBLER_TEST_GENERATE(Fcvtzdsw, assembler) {
-  __ LoadDImmediate(V0, 42.0);
-  __ fcvtzdsw(R0, V0);
-  __ ret();
-}
-
-ASSEMBLER_TEST_RUN(Fcvtzdsw, test) {
-  typedef int64_t (*Int64Return)() DART_UNUSED;
-  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
-}
-
-ASSEMBLER_TEST_GENERATE(Fcvtzdsx_overflow, assembler) {
-  __ LoadDImmediate(V0, 1e20);
-  __ fcvtzdsx(R0, V0);
-  __ ret();
-}
-
-ASSEMBLER_TEST_RUN(Fcvtzdsx_overflow, test) {
-  typedef int64_t (*Int64Return)() DART_UNUSED;
-  EXPECT_EQ(kMaxInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
-}
-
-ASSEMBLER_TEST_GENERATE(Fcvtzdsx_overflow_negative, assembler) {
-  __ LoadDImmediate(V0, -1e20);
-  __ fcvtzdsx(R0, V0);
-  __ ret();
-}
-
-ASSEMBLER_TEST_RUN(Fcvtzdsx_overflow_negative, test) {
-  typedef int64_t (*Int64Return)() DART_UNUSED;
-  EXPECT_EQ(kMinInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
-}
-
-ASSEMBLER_TEST_GENERATE(Fcvtzdsw_overflow, assembler) {
-  __ LoadDImmediate(V0, 1e10);
-  __ fcvtzdsw(R0, V0);
-  __ ret();
-}
-
-ASSEMBLER_TEST_RUN(Fcvtzdsw_overflow, test) {
-  typedef int64_t (*Int64Return)() DART_UNUSED;
-  EXPECT_EQ(kMaxInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
-}
-
-ASSEMBLER_TEST_GENERATE(Fcvtzdsw_overflow_negative, assembler) {
-  __ LoadDImmediate(V0, -1e10);
-  __ fcvtzdsw(R0, V0);
+ASSEMBLER_TEST_GENERATE(Fcvtzswd, assembler) {
+  __ LoadDImmediate(V0, -42.5);
+  __ fcvtzswd(R0, V0);
   __ sxtw(R0, R0);
   __ ret();
 }
 
-ASSEMBLER_TEST_RUN(Fcvtzdsw_overflow_negative, test) {
+ASSEMBLER_TEST_RUN(Fcvtzswd, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(-42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzsxd_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e20);
+  __ fcvtzsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzsxd_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzsxd_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e20);
+  __ fcvtzsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzsxd_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzswd_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e10);
+  __ fcvtzswd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzswd_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtzswd_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e10);
+  __ fcvtzswd(R0, V0);
+  __ sxtw(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtzswd_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtpsxd, assembler) {
+  __ LoadDImmediate(V0, 42.5);
+  __ fcvtpsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtpsxd, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(43, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtpswd, assembler) {
+  __ LoadDImmediate(V0, -42.5);
+  __ fcvtpswd(R0, V0);
+  __ sxtw(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtpswd, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(-42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtpsxd_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e20);
+  __ fcvtpsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtpsxd_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtpsxd_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e20);
+  __ fcvtpsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtpsxd_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtpswd_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e10);
+  __ fcvtpswd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtpswd_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtpswd_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e10);
+  __ fcvtpswd(R0, V0);
+  __ sxtw(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtpswd_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtmsxd, assembler) {
+  __ LoadDImmediate(V0, 42.5);
+  __ fcvtmsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtmsxd, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtmswd, assembler) {
+  __ LoadDImmediate(V0, -42.5);
+  __ fcvtmswd(R0, V0);
+  __ sxtw(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtmswd, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(-43, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtmsxd_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e20);
+  __ fcvtmsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtmsxd_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtmsxd_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e20);
+  __ fcvtmsxd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtmsxd_overflow_negative, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMinInt64, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtmswd_overflow, assembler) {
+  __ LoadDImmediate(V0, 1e10);
+  __ fcvtmswd(R0, V0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtmswd_overflow, test) {
+  typedef int64_t (*Int64Return)() DART_UNUSED;
+  EXPECT_EQ(kMaxInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(Fcvtmswd_overflow_negative, assembler) {
+  __ LoadDImmediate(V0, -1e10);
+  __ fcvtmswd(R0, V0);
+  __ sxtw(R0, R0);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Fcvtmswd_overflow_negative, test) {
   typedef int64_t (*Int64Return)() DART_UNUSED;
   EXPECT_EQ(kMinInt32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
 }
diff --git a/runtime/vm/compiler/assembler/disassembler_arm64.cc b/runtime/vm/compiler/assembler/disassembler_arm64.cc
index 08529fe..8f441ef 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm64.cc
@@ -1435,8 +1435,12 @@
       Format(instr, "fmovrd'sf 'rd, 'vn");
     } else if (instr->Bits(16, 5) == 7) {
       Format(instr, "fmovdr'sf 'vd, 'rn");
+    } else if (instr->Bits(16, 5) == 8) {
+      Format(instr, "fcvtps'sf 'rd, 'vn");
+    } else if (instr->Bits(16, 5) == 16) {
+      Format(instr, "fcvtms'sf 'rd, 'vn");
     } else if (instr->Bits(16, 5) == 24) {
-      Format(instr, "fcvtzds'sf 'rd, 'vn");
+      Format(instr, "fcvtzs'sf 'rd, 'vn");
     } else {
       Unknown(instr);
     }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index c49546e..4d80627 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -298,9 +298,11 @@
   const Register result_;
 };
 
-class DoubleToIntegerSlowPath : public TemplateSlowPathCode<Instruction> {
+class DoubleToIntegerSlowPath
+    : public TemplateSlowPathCode<DoubleToIntegerInstr> {
  public:
-  DoubleToIntegerSlowPath(Instruction* instruction, FpuRegister value_reg)
+  DoubleToIntegerSlowPath(DoubleToIntegerInstr* instruction,
+                          FpuRegister value_reg)
       : TemplateSlowPathCode(instruction), value_reg_(value_reg) {}
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler);
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 215b0cc..7f82524 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -5617,6 +5617,9 @@
       compiler->SlowPathEnvironmentFor(instruction(), /*num_slow_path_args=*/0);
 
   __ MoveUnboxedDouble(DoubleToIntegerStubABI::kInputReg, value_reg_);
+  __ LoadImmediate(
+      DoubleToIntegerStubABI::kRecognizedKindReg,
+      compiler::target::ToRawSmi(instruction()->recognized_kind()));
   compiler->GenerateStubCall(instruction()->source(),
                              StubCode::DoubleToInteger(),
                              UntaggedPcDescriptors::kOther, locs,
@@ -6200,10 +6203,10 @@
 intptr_t InvokeMathCFunctionInstr::ArgumentCountFor(
     MethodRecognizer::Kind kind) {
   switch (kind) {
-    case MethodRecognizer::kDoubleTruncate:
-    case MethodRecognizer::kDoubleFloor:
-    case MethodRecognizer::kDoubleCeil:
-    case MethodRecognizer::kDoubleRound:
+    case MethodRecognizer::kDoubleTruncateToDouble:
+    case MethodRecognizer::kDoubleFloorToDouble:
+    case MethodRecognizer::kDoubleCeilToDouble:
+    case MethodRecognizer::kDoubleRoundToDouble:
     case MethodRecognizer::kMathAtan:
     case MethodRecognizer::kMathTan:
     case MethodRecognizer::kMathAcos:
@@ -6225,13 +6228,13 @@
 
 const RuntimeEntry& InvokeMathCFunctionInstr::TargetFunction() const {
   switch (recognized_kind_) {
-    case MethodRecognizer::kDoubleTruncate:
+    case MethodRecognizer::kDoubleTruncateToDouble:
       return kLibcTruncRuntimeEntry;
-    case MethodRecognizer::kDoubleRound:
+    case MethodRecognizer::kDoubleRoundToDouble:
       return kLibcRoundRuntimeEntry;
-    case MethodRecognizer::kDoubleFloor:
+    case MethodRecognizer::kDoubleFloorToDouble:
       return kLibcFloorRuntimeEntry;
-    case MethodRecognizer::kDoubleCeil:
+    case MethodRecognizer::kDoubleCeilToDouble:
       return kLibcCeilRuntimeEntry;
     case MethodRecognizer::kMathDoublePow:
       return kLibcPowRuntimeEntry;
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 38823bd..a6f9d2d 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -8320,13 +8320,20 @@
 
 class DoubleToIntegerInstr : public TemplateDefinition<1, Throws, Pure> {
  public:
-  DoubleToIntegerInstr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
+  DoubleToIntegerInstr(Value* value,
+                       MethodRecognizer::Kind recognized_kind,
+                       intptr_t deopt_id)
+      : TemplateDefinition(deopt_id), recognized_kind_(recognized_kind) {
+    ASSERT((recognized_kind == MethodRecognizer::kDoubleToInteger) ||
+           (recognized_kind == MethodRecognizer::kDoubleFloorToInt) ||
+           (recognized_kind == MethodRecognizer::kDoubleCeilToInt));
     SetInputAt(0, value);
   }
 
   Value* value() const { return inputs_[0]; }
 
+  MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; }
+
   DECLARE_INSTRUCTION(DoubleToInteger)
   virtual CompileType ComputeType() const;
 
@@ -8348,9 +8355,13 @@
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
-  virtual bool AttributesEqual(const Instruction& other) const { return true; }
+  virtual bool AttributesEqual(const Instruction& other) const {
+    return other.AsDoubleToInteger()->recognized_kind() == recognized_kind();
+  }
 
  private:
+  const MethodRecognizer::Kind recognized_kind_;
+
   DISALLOW_COPY_AND_ASSIGN(DoubleToIntegerInstr);
 };
 
@@ -8389,6 +8400,9 @@
                       MethodRecognizer::Kind recognized_kind,
                       intptr_t deopt_id)
       : TemplateDefinition(deopt_id), recognized_kind_(recognized_kind) {
+    ASSERT((recognized_kind == MethodRecognizer::kDoubleTruncateToDouble) ||
+           (recognized_kind == MethodRecognizer::kDoubleFloorToDouble) ||
+           (recognized_kind == MethodRecognizer::kDoubleCeilToDouble));
     SetInputAt(0, value);
   }
 
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 0a7f6fa..3550f0c 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -4914,12 +4914,24 @@
   compiler->AddSlowPathCode(slow_path);
 
   // First check for NaN. Checking for minint after the conversion doesn't work
-  // on ARM64 because fcvtzds gives 0 for NaN.
+  // on ARM64 because fcvtzs gives 0 for NaN.
   __ fcmpd(value_double, value_double);
   __ b(slow_path->entry_label(), VS);
 
-  __ fcvtzdsx(result, value_double);
-  // Overflow is signaled with minint.
+  switch (recognized_kind()) {
+    case MethodRecognizer::kDoubleToInteger:
+      __ fcvtzsxd(result, value_double);
+      break;
+    case MethodRecognizer::kDoubleFloorToInt:
+      __ fcvtmsxd(result, value_double);
+      break;
+    case MethodRecognizer::kDoubleCeilToInt:
+      __ fcvtpsxd(result, value_double);
+      break;
+    default:
+      UNREACHABLE();
+  }
+    // Overflow is signaled with minint.
 
 #if !defined(DART_COMPRESSED_POINTERS)
   // Check for overflow and that it fits into Smi.
@@ -4952,12 +4964,12 @@
   const Register result = locs()->out(0).reg();
   const VRegister value = locs()->in(0).fpu_reg();
   // First check for NaN. Checking for minint after the conversion doesn't work
-  // on ARM64 because fcvtzds gives 0 for NaN.
+  // on ARM64 because fcvtzs gives 0 for NaN.
   // TODO(zra): Check spec that this is true.
   __ fcmpd(value, value);
   __ b(deopt, VS);
 
-  __ fcvtzdsx(result, value);
+  __ fcvtzsxd(result, value);
 
 #if !defined(DART_COMPRESSED_POINTERS)
   // Check for overflow and that it fits into Smi.
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 715362c..198e2d4 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -5021,6 +5021,7 @@
 }
 
 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(recognized_kind() == MethodRecognizer::kDoubleToInteger);
   const Register result = locs()->out(0).reg();
   const XmmRegister value_double = locs()->in(0).fpu_reg();
 
@@ -5075,13 +5076,13 @@
   XmmRegister value = locs()->in(0).fpu_reg();
   XmmRegister result = locs()->out(0).fpu_reg();
   switch (recognized_kind()) {
-    case MethodRecognizer::kDoubleTruncate:
+    case MethodRecognizer::kDoubleTruncateToDouble:
       __ roundsd(result, value, compiler::Assembler::kRoundToZero);
       break;
-    case MethodRecognizer::kDoubleFloor:
+    case MethodRecognizer::kDoubleFloorToDouble:
       __ roundsd(result, value, compiler::Assembler::kRoundDown);
       break;
-    case MethodRecognizer::kDoubleCeil:
+    case MethodRecognizer::kDoubleCeilToDouble:
       __ roundsd(result, value, compiler::Assembler::kRoundUp);
       break;
     default:
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 09a4344..e780e03 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -5216,13 +5216,45 @@
 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register result = locs()->out(0).reg();
   const Register temp = locs()->temp(0).reg();
-  const XmmRegister value_double = locs()->in(0).fpu_reg();
+  XmmRegister value_double = locs()->in(0).fpu_reg();
   ASSERT(result != temp);
 
   DoubleToIntegerSlowPath* slow_path =
       new DoubleToIntegerSlowPath(this, value_double);
   compiler->AddSlowPathCode(slow_path);
 
+  if (recognized_kind() != MethodRecognizer::kDoubleToInteger) {
+    // In JIT mode VM knows target CPU features at compile time
+    // and can pick more optimal representation for DoubleToDouble
+    // conversion. In AOT mode we test if roundsd instruction is
+    // available at run time and fall back to stub if it isn't.
+    ASSERT(CompilerState::Current().is_aot());
+    if (FLAG_use_slow_path) {
+      __ jmp(slow_path->entry_label());
+      __ Bind(slow_path->exit_label());
+      return;
+    }
+    __ cmpb(
+        compiler::Address(
+            THR,
+            compiler::target::Thread::double_truncate_round_supported_offset()),
+        compiler::Immediate(0));
+    __ j(EQUAL, slow_path->entry_label());
+
+    __ xorps(FpuTMP, FpuTMP);
+    switch (recognized_kind()) {
+      case MethodRecognizer::kDoubleFloorToInt:
+        __ roundsd(FpuTMP, value_double, compiler::Assembler::kRoundDown);
+        break;
+      case MethodRecognizer::kDoubleCeilToInt:
+        __ roundsd(FpuTMP, value_double, compiler::Assembler::kRoundUp);
+        break;
+      default:
+        UNREACHABLE();
+    }
+    value_double = FpuTMP;
+  }
+
   __ OBJ(cvttsd2si)(result, value_double);
   // Overflow is signalled with minint.
   // Check for overflow and that it fits into Smi.
@@ -5282,13 +5314,13 @@
     __ xorps(result, result);
   }
   switch (recognized_kind()) {
-    case MethodRecognizer::kDoubleTruncate:
+    case MethodRecognizer::kDoubleTruncateToDouble:
       __ roundsd(result, value, compiler::Assembler::kRoundToZero);
       break;
-    case MethodRecognizer::kDoubleFloor:
+    case MethodRecognizer::kDoubleFloorToDouble:
       __ roundsd(result, value, compiler::Assembler::kRoundDown);
       break;
-    case MethodRecognizer::kDoubleCeil:
+    case MethodRecognizer::kDoubleCeilToDouble:
       __ roundsd(result, value, compiler::Assembler::kRoundUp);
       break;
     default:
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 84df214..90d1657 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -1010,8 +1010,8 @@
         Definition* d2i_instr = NULL;
         if (ic_data.HasDeoptReason(ICData::kDeoptDoubleToSmi)) {
           // Do not repeatedly deoptimize because result didn't fit into Smi.
-          d2i_instr = new (Z)
-              DoubleToIntegerInstr(new (Z) Value(input), call->deopt_id());
+          d2i_instr = new (Z) DoubleToIntegerInstr(
+              new (Z) Value(input), recognized_kind, call->deopt_id());
         } else {
           // Optimistically assume result fits into Smi.
           d2i_instr =
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 34d3ebf..b16a368 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -1217,9 +1217,11 @@
   return Fragment(instr);
 }
 
-Fragment BaseFlowGraphBuilder::DoubleToInteger() {
+Fragment BaseFlowGraphBuilder::DoubleToInteger(
+    MethodRecognizer::Kind recognized_kind) {
   Value* value = Pop();
-  auto* instr = new (Z) DoubleToIntegerInstr(value, GetNextDeoptId());
+  auto* instr =
+      new (Z) DoubleToIntegerInstr(value, recognized_kind, GetNextDeoptId());
   Push(instr);
   return Fragment(instr);
 }
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 2ca80a6..0a5339f 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -451,12 +451,14 @@
                                intptr_t num_inputs);
 
   // Pops double value and converts it to double as specified
-  // by the recognized method (kDoubleTruncate,
-  // kDoubleFloor or kDoubleCeil).
+  // by the recognized method (kDoubleTruncateToDouble,
+  // kDoubleFloorToDouble or kDoubleCeilToDouble).
   Fragment DoubleToDouble(MethodRecognizer::Kind recognized_kind);
 
-  // Pops double value and converts it to int.
-  Fragment DoubleToInteger();
+  // Pops double value and converts it to int as specified
+  // by the recognized method (kDoubleToInteger,
+  // kDoubleFloorToInt or kDoubleCeilToInt).
+  Fragment DoubleToInteger(MethodRecognizer::Kind recognized_kind);
 
   // Pops double value and applies unary math operation.
   Fragment MathUnary(MathUnaryInstr::MathUnaryKind kind);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 52d7171..87ac359 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -897,10 +897,10 @@
       return true;
     case MethodRecognizer::kDoubleToInteger:
     case MethodRecognizer::kDoubleMod:
-    case MethodRecognizer::kDoubleRound:
-    case MethodRecognizer::kDoubleTruncate:
-    case MethodRecognizer::kDoubleFloor:
-    case MethodRecognizer::kDoubleCeil:
+    case MethodRecognizer::kDoubleRoundToDouble:
+    case MethodRecognizer::kDoubleTruncateToDouble:
+    case MethodRecognizer::kDoubleFloorToDouble:
+    case MethodRecognizer::kDoubleCeilToDouble:
     case MethodRecognizer::kMathDoublePow:
     case MethodRecognizer::kMathSin:
     case MethodRecognizer::kMathCos:
@@ -913,6 +913,16 @@
     case MethodRecognizer::kMathLog:
     case MethodRecognizer::kMathSqrt:
       return FlowGraphCompiler::SupportsUnboxedDoubles();
+    case MethodRecognizer::kDoubleCeilToInt:
+    case MethodRecognizer::kDoubleFloorToInt:
+      if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+#if defined(TARGET_ARCH_X64)
+      return CompilerState::Current().is_aot();
+#elif defined(TARGET_ARCH_ARM64)
+      return true;
+#else
+      return false;
+#endif
     default:
       return false;
   }
@@ -1540,15 +1550,17 @@
       body += LoadIndexed(kIntPtrCid);
       body += Box(kUnboxedIntPtr);
     } break;
-    case MethodRecognizer::kDoubleToInteger: {
+    case MethodRecognizer::kDoubleToInteger:
+    case MethodRecognizer::kDoubleCeilToInt:
+    case MethodRecognizer::kDoubleFloorToInt: {
       body += LoadLocal(parsed_function_->RawParameterVariable(0));
-      body += DoubleToInteger();
+      body += DoubleToInteger(kind);
     } break;
     case MethodRecognizer::kDoubleMod:
-    case MethodRecognizer::kDoubleRound:
-    case MethodRecognizer::kDoubleTruncate:
-    case MethodRecognizer::kDoubleFloor:
-    case MethodRecognizer::kDoubleCeil:
+    case MethodRecognizer::kDoubleRoundToDouble:
+    case MethodRecognizer::kDoubleTruncateToDouble:
+    case MethodRecognizer::kDoubleFloorToDouble:
+    case MethodRecognizer::kDoubleCeilToDouble:
     case MethodRecognizer::kMathDoublePow:
     case MethodRecognizer::kMathSin:
     case MethodRecognizer::kMathCos:
@@ -1564,9 +1576,9 @@
       }
       if (!CompilerState::Current().is_aot() &&
           TargetCPUFeatures::double_truncate_round_supported() &&
-          ((kind == MethodRecognizer::kDoubleTruncate) ||
-           (kind == MethodRecognizer::kDoubleFloor) ||
-           (kind == MethodRecognizer::kDoubleCeil))) {
+          ((kind == MethodRecognizer::kDoubleTruncateToDouble) ||
+           (kind == MethodRecognizer::kDoubleFloorToDouble) ||
+           (kind == MethodRecognizer::kDoubleCeilToDouble))) {
         body += DoubleToDouble(kind);
       } else {
         body += InvokeMathCFunction(kind, function.NumParameters());
diff --git a/runtime/vm/compiler/offsets_extractor.cc b/runtime/vm/compiler/offsets_extractor.cc
index 454457d..e1f2f1f 100644
--- a/runtime/vm/compiler/offsets_extractor.cc
+++ b/runtime/vm/compiler/offsets_extractor.cc
@@ -37,7 +37,7 @@
 
 namespace dart {
 
-void Assert::Fail(const char* format, ...) {
+void Assert::Fail(const char* format, ...) const {
   abort();
 }
 
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 554d11b..bc55064 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -88,11 +88,13 @@
   V(_Double, _mul, DoubleMul, 0x1f98c76c)                                      \
   V(_Double, _div, DoubleDiv, 0x287d3791)                                      \
   V(_Double, _modulo, DoubleMod, 0xfdb397ef)                                   \
-  V(_Double, ceilToDouble, DoubleCeil, 0x5f1bced9)                             \
-  V(_Double, floorToDouble, DoubleFloor, 0x54b4cb48)                           \
-  V(_Double, roundToDouble, DoubleRound, 0x5649ca00)                           \
+  V(_Double, ceil, DoubleCeilToInt, 0xcef8d7c5)                                \
+  V(_Double, ceilToDouble, DoubleCeilToDouble, 0x5f1bced9)                     \
+  V(_Double, floor, DoubleFloorToInt, 0x2a323f88)                              \
+  V(_Double, floorToDouble, DoubleFloorToDouble, 0x54b4cb48)                   \
+  V(_Double, roundToDouble, DoubleRoundToDouble, 0x5649ca00)                   \
   V(_Double, toInt, DoubleToInteger, 0x676f20a9)                               \
-  V(_Double, truncateToDouble, DoubleTruncate, 0x62d48659)                     \
+  V(_Double, truncateToDouble, DoubleTruncateToDouble, 0x62d48659)             \
   V(::, min, MathMin, 0x504a28df)                                              \
   V(::, max, MathMax, 0xead7161a)                                              \
   V(::, _doublePow, MathDoublePow, 0x989f3334)                                 \
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index d2e9510..beff8e5 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -1056,6 +1056,7 @@
 class Thread : public AllStatic {
  public:
   static word api_top_scope_offset();
+  static word double_truncate_round_supported_offset();
   static word exit_through_ffi_offset();
   static uword exit_through_runtime_call();
   static uword exit_through_ffi();
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 72ec4ff..9cb8a94 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -222,12 +222,11 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    184;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
+    152;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 108;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    212;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    104;
+    172;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -286,9 +285,11 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 796;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 800;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 792;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
@@ -330,7 +331,7 @@
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
     784;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 800;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 804;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -769,12 +770,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -838,6 +839,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1600;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -1321,12 +1324,11 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    184;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
+    152;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 108;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    212;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    104;
+    172;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -1385,9 +1387,11 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 764;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 768;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 760;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
@@ -1429,7 +1433,7 @@
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
     752;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 768;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 772;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -1865,12 +1869,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -1934,6 +1938,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1664;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -2418,12 +2424,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -2487,6 +2493,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1600;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -2970,12 +2978,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -3039,6 +3047,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1664;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -3519,12 +3529,11 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    184;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
+    152;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 108;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    212;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    104;
+    172;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -3583,9 +3592,11 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 796;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 800;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 792;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
@@ -3627,7 +3638,7 @@
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
     784;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 800;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 804;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -4060,12 +4071,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -4129,6 +4140,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1600;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -4606,12 +4619,11 @@
     12;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    184;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 124;
+    152;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 108;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    212;
-static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    104;
+    172;
+static constexpr dart::compiler::target::word ObjectStore_type_type_offset = 96;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 12;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 4;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset = 8;
@@ -4670,9 +4682,11 @@
     Thread_call_to_runtime_entry_point_offset = 276;
 static constexpr dart::compiler::target::word
     Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 764;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 768;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 760;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232;
@@ -4714,7 +4728,7 @@
 static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
     752;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 768;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 772;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
 static constexpr dart::compiler::target::word
@@ -5144,12 +5158,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -5213,6 +5227,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1664;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -5691,12 +5707,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -5760,6 +5776,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1600;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -6237,12 +6255,12 @@
     24;
 static constexpr dart::compiler::target::word NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
-    368;
-static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 248;
+    304;
+static constexpr dart::compiler::target::word ObjectStore_int_type_offset = 216;
 static constexpr dart::compiler::target::word ObjectStore_string_type_offset =
-    424;
+    344;
 static constexpr dart::compiler::target::word ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word OneByteString_data_offset = 16;
 static constexpr dart::compiler::target::word PointerBase_data_field_offset = 8;
 static constexpr dart::compiler::target::word Pointer_type_arguments_offset =
@@ -6306,6 +6324,8 @@
 static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1664;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448;
@@ -6815,13 +6835,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 184;
+    AOT_ObjectStore_double_type_offset = 152;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    124;
+    108;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 212;
+    AOT_ObjectStore_string_type_offset = 172;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    104;
+    96;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word
@@ -6888,9 +6908,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    796;
+    800;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 792;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -6934,7 +6956,7 @@
     AOT_Thread_exit_through_ffi_offset = 784;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    800;
+    804;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
 static constexpr dart::compiler::target::word
@@ -7426,13 +7448,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -7502,6 +7524,8 @@
     1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -8043,13 +8067,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -8119,6 +8143,8 @@
     1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -8657,13 +8683,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -8733,6 +8759,8 @@
     1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -9270,13 +9298,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -9346,6 +9374,8 @@
     1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -9879,13 +9909,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 184;
+    AOT_ObjectStore_double_type_offset = 152;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    124;
+    108;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 212;
+    AOT_ObjectStore_string_type_offset = 172;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    104;
+    96;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     12;
 static constexpr dart::compiler::target::word
@@ -9952,9 +9982,11 @@
 static constexpr dart::compiler::target::word
     AOT_Thread_call_to_runtime_stub_offset = 144;
 static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
-    796;
+    800;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 792;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     316;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -9998,7 +10030,7 @@
     AOT_Thread_exit_through_ffi_offset = 784;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
-    800;
+    804;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
 static constexpr dart::compiler::target::word
@@ -10483,13 +10515,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -10559,6 +10591,8 @@
     1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -11093,13 +11127,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -11169,6 +11203,8 @@
     1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -11700,13 +11736,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -11776,6 +11812,8 @@
     1600;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1592;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
@@ -12306,13 +12344,13 @@
 static constexpr dart::compiler::target::word
     AOT_NativeArguments_thread_offset = 0;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_double_type_offset = 368;
+    AOT_ObjectStore_double_type_offset = 304;
 static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
-    248;
+    216;
 static constexpr dart::compiler::target::word
-    AOT_ObjectStore_string_type_offset = 424;
+    AOT_ObjectStore_string_type_offset = 344;
 static constexpr dart::compiler::target::word AOT_ObjectStore_type_type_offset =
-    208;
+    192;
 static constexpr dart::compiler::target::word AOT_OneByteString_data_offset =
     16;
 static constexpr dart::compiler::target::word
@@ -12382,6 +12420,8 @@
     1664;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
+static constexpr dart::compiler::target::word
+    AOT_Thread_double_truncate_round_supported_offset = 1656;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
     616;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset =
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 65505e1..2e97ede 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -213,6 +213,7 @@
   FIELD(Thread, call_to_runtime_stub_offset)                                   \
   FIELD(Thread, dart_stream_offset)                                            \
   FIELD(Thread, dispatch_table_array_offset)                                   \
+  FIELD(Thread, double_truncate_round_supported_offset)                        \
   FIELD(Thread, optimize_entry_offset)                                         \
   FIELD(Thread, optimize_stub_offset)                                          \
   FIELD(Thread, deoptimize_entry_offset)                                       \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 7b3e42e..c340571 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -1061,7 +1061,9 @@
   __ StoreUnboxedDouble(DoubleToIntegerStubABI::kInputReg, THR,
                         target::Thread::unboxed_double_runtime_arg_offset());
   __ PushObject(NullObject()); /* Make room for result. */
-  __ CallRuntime(kDoubleToIntegerRuntimeEntry, 0);
+  __ PushRegister(DoubleToIntegerStubABI::kRecognizedKindReg);
+  __ CallRuntime(kDoubleToIntegerRuntimeEntry, 1);
+  __ Drop(1);
   __ PopRegister(DoubleToIntegerStubABI::kResultReg);
   __ LeaveStubFrame();
   __ Ret();
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 05f2342..bf28845 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -497,6 +497,7 @@
 // ABI for DoubleToIntegerStub.
 struct DoubleToIntegerStubABI {
   static const FpuRegister kInputReg = Q0;
+  static const Register kRecognizedKindReg = R0;
   static const Register kResultReg = R0;
 };
 
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index c661cc2..2279f02 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -337,6 +337,7 @@
 // ABI for DoubleToIntegerStub.
 struct DoubleToIntegerStubABI {
   static const FpuRegister kInputReg = V0;
+  static const Register kRecognizedKindReg = R0;
   static const Register kResultReg = R0;
 };
 
@@ -930,7 +931,9 @@
   FMOVSR = FPIntCvtFixed | B18 | B17 | B16,
   FMOVRD = FPIntCvtFixed | B22 | B18 | B17,
   FMOVDR = FPIntCvtFixed | B22 | B18 | B17 | B16,
-  FCVTZDS = FPIntCvtFixed | B22 | B20 | B19,
+  FCVTZS_D = FPIntCvtFixed | B22 | B20 | B19,
+  FCVTMS_D = FPIntCvtFixed | B22 | B20,
+  FCVTPS_D = FPIntCvtFixed | B22 | B19,
   SCVTFD = FPIntCvtFixed | B22 | B17,
 };
 
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 5bbb8e6..5f9c331 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -236,6 +236,7 @@
 // ABI for DoubleToIntegerStub.
 struct DoubleToIntegerStubABI {
   static const FpuRegister kInputReg = XMM0;
+  static const Register kRecognizedKindReg = EAX;
   static const Register kResultReg = EAX;
 };
 
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 73296ae..c776976 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -309,6 +309,7 @@
 // ABI for DoubleToIntegerStub.
 struct DoubleToIntegerStubABI {
   static const FpuRegister kInputReg = XMM0;
+  static const Register kRecognizedKindReg = RAX;
   static const Register kResultReg = RAX;
 };
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 7655866..38b1022 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -340,6 +340,7 @@
   NOT_IN_PRODUCT(Metric::Init());
   StoreBuffer::Init();
   MarkingStack::Init();
+  TargetCPUFeatures::Init();
 
 #if defined(USING_SIMULATOR)
   Simulator::Init();
@@ -387,7 +388,6 @@
     Object::InitNullAndBool(vm_isolate_->group());
     vm_isolate_->isolate_group_->set_object_store(new ObjectStore());
     vm_isolate_->isolate_object_store()->Init();
-    TargetCPUFeatures::Init();
     Object::Init(vm_isolate_->group());
     OffsetsTable::Init();
     ArgumentsDescriptor::Init();
diff --git a/runtime/vm/ffi_callback_trampolines.cc b/runtime/vm/ffi_callback_trampolines.cc
index 8cc1946..fd73c3c 100644
--- a/runtime/vm/ffi_callback_trampolines.cc
+++ b/runtime/vm/ffi_callback_trampolines.cc
@@ -48,7 +48,9 @@
     VirtualMemory* const memory = VirtualMemory::AllocateAligned(
         /*size=*/VirtualMemory::PageSize(),
         /*alignment=*/VirtualMemory::PageSize(),
-        /*is_executable=*/true, /*name=*/"Dart VM FFI callback trampolines");
+        /*is_executable=*/true,
+        /*is_compressed=*/false,
+        /*name=*/"Dart VM FFI callback trampolines");
     memory->Protect(VirtualMemory::kReadWrite);
 
     if (memory == nullptr) {
diff --git a/runtime/vm/heap/freelist_test.cc b/runtime/vm/heap/freelist_test.cc
index 4e7b7f4..5778886 100644
--- a/runtime/vm/heap/freelist_test.cc
+++ b/runtime/vm/heap/freelist_test.cc
@@ -84,8 +84,8 @@
 TEST_CASE(FreeList) {
   FreeList* free_list = new FreeList();
   const intptr_t kBlobSize = 1 * MB;
-  VirtualMemory* region =
-      VirtualMemory::Allocate(kBlobSize, /* is_executable */ false, "test");
+  VirtualMemory* region = VirtualMemory::Allocate(
+      kBlobSize, /* is_executable */ false, /* is_compressed */ false, "test");
 
   TestFreeList(region, free_list, false);
 
@@ -97,8 +97,8 @@
 TEST_CASE(FreeListProtected) {
   FreeList* free_list = new FreeList();
   const intptr_t kBlobSize = 1 * MB;
-  VirtualMemory* region =
-      VirtualMemory::Allocate(kBlobSize, /* is_executable */ false, "test");
+  VirtualMemory* region = VirtualMemory::Allocate(
+      kBlobSize, /*is_executable*/ false, /*is_compressed*/ false, "test");
 
   TestFreeList(region, free_list, true);
 
@@ -113,8 +113,8 @@
   const intptr_t kObjectSize = 2 * kWordSize;
   uword* objects = new uword[kBlobSize / kObjectSize];
 
-  VirtualMemory* blob =
-      VirtualMemory::Allocate(kBlobSize, /* is_executable = */ false, "test");
+  VirtualMemory* blob = VirtualMemory::Allocate(
+      kBlobSize, /*is_executable*/ false, /*is_compressed*/ false, "test");
   ASSERT(Utils::IsAligned(blob->start(), 4096));
   blob->Protect(VirtualMemory::kReadWrite);
 
@@ -154,8 +154,8 @@
     objects[i] = static_cast<uword>(NULL);
   }
 
-  VirtualMemory* blob =
-      VirtualMemory::Allocate(kBlobSize, /* is_executable = */ false, "test");
+  VirtualMemory* blob = VirtualMemory::Allocate(
+      kBlobSize, /*is_executable*/ false, /*is_compressed*/ false, "test");
   blob->Protect(VirtualMemory::kReadWrite);
 
   // Enqueue the large blob as one free block.
@@ -197,9 +197,9 @@
   // "<other code>" region is also still executable (and not writable).
   std::unique_ptr<FreeList> free_list(new FreeList());
   const uword page = VirtualMemory::PageSize();
-  std::unique_ptr<VirtualMemory> blob(
-      VirtualMemory::Allocate(2 * page,
-                              /*is_executable=*/false, "test"));
+  std::unique_ptr<VirtualMemory> blob(VirtualMemory::Allocate(
+      2 * page,
+      /*is_executable=*/false, /*is_compressed*/ false, "test"));
   const intptr_t remainder_size = page / 2;
   const intptr_t alloc_size = page - header_overlap * kObjectAlignment;
   void* const other_code =
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index dc87ca1..0cda99e 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -47,9 +47,11 @@
                            PageType type,
                            const char* name) {
   const bool executable = type == kExecutable;
+  const bool compressed = !executable;
 
   VirtualMemory* memory = VirtualMemory::AllocateAligned(
-      size_in_words << kWordSizeLog2, kOldPageSize, executable, name);
+      size_in_words << kWordSizeLog2, kOldPageSize, executable, compressed,
+      name);
   if (memory == NULL) {
     return NULL;
   }
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index cf52ef4..78b0ad3 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -669,9 +669,10 @@
   if (memory == nullptr) {
     const intptr_t alignment = kNewPageSize;
     const bool is_executable = false;
+    const bool compressed = true;
     const char* const name = Heap::RegionName(Heap::kNew);
-    memory =
-        VirtualMemory::AllocateAligned(size, alignment, is_executable, name);
+    memory = VirtualMemory::AllocateAligned(size, alignment, is_executable,
+                                            compressed, name);
   }
   if (memory == nullptr) {
     return nullptr;  // Out of memory.
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6ea4ade..bae028b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1757,10 +1757,6 @@
     type.SetIsFinalized();
     type ^= type.Canonicalize(thread, nullptr);
     object_store->set_array_type(type);
-    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_array_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_array_type(type);
 
     cls = object_store->growable_object_array_class();  // Was allocated above.
     RegisterPrivateClass(cls, Symbols::_GrowableList(), core_lib);
@@ -2150,20 +2146,12 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_function_type(type);
-    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_function_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_function_type(type);
 
     cls = Class::New<Number, RTN::Number>(isolate_group);
     RegisterClass(cls, Symbols::Number(), core_lib);
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_number_type(type);
-    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_number_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_number_type(type);
 
     cls = Class::New<Instance, RTN::Instance>(kIllegalCid, isolate_group,
                                               /*register_class=*/true,
@@ -2190,10 +2178,6 @@
     pending_classes.Add(cls);
     type = Type::NewNonParameterizedType(cls);
     object_store->set_double_type(type);
-    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_double_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_double_type(type);
     type = type.ToNullability(Nullability::kNullable, Heap::kOld);
     object_store->set_nullable_double_type(type);
 
@@ -2209,32 +2193,19 @@
     object_store->set_string_type(type);
     type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
     object_store->set_legacy_string_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_string_type(type);
 
     cls = object_store->bool_class();
     type = Type::NewNonParameterizedType(cls);
     object_store->set_bool_type(type);
-    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_bool_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_bool_type(type);
 
     cls = object_store->smi_class();
     type = Type::NewNonParameterizedType(cls);
     object_store->set_smi_type(type);
     type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_smi_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_smi_type(type);
 
     cls = object_store->mint_class();
     type = Type::NewNonParameterizedType(cls);
     object_store->set_mint_type(type);
-    type = type.ToNullability(Nullability::kLegacy, Heap::kOld);
-    object_store->set_legacy_mint_type(type);
-    type = type.ToNullability(Nullability::kNonNullable, Heap::kOld);
-    object_store->set_non_nullable_mint_type(type);
 
     // The classes 'void' and 'dynamic' are phony classes to make type checking
     // more regular; they live in the VM isolate. The class 'void' is not
@@ -2274,27 +2245,12 @@
     type_args.SetTypeAt(0, type);
     type_args = type_args.Canonicalize(thread, nullptr);
     object_store->set_type_argument_legacy_int(type_args);
-    type_args = TypeArguments::New(1);
-    type = object_store->non_nullable_int_type();
-    type_args.SetTypeAt(0, type);
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_non_nullable_int(type_args);
 
     type_args = TypeArguments::New(1);
     type = object_store->double_type();
     type_args.SetTypeAt(0, type);
     type_args = type_args.Canonicalize(thread, nullptr);
     object_store->set_type_argument_double(type_args);
-    type_args = TypeArguments::New(1);
-    type = object_store->legacy_double_type();
-    type_args.SetTypeAt(0, type);
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_legacy_double(type_args);
-    type_args = TypeArguments::New(1);
-    type = object_store->non_nullable_double_type();
-    type_args.SetTypeAt(0, type);
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_non_nullable_double(type_args);
 
     type_args = TypeArguments::New(1);
     type = object_store->string_type();
@@ -2306,11 +2262,6 @@
     type_args.SetTypeAt(0, type);
     type_args = type_args.Canonicalize(thread, nullptr);
     object_store->set_type_argument_legacy_string(type_args);
-    type_args = TypeArguments::New(1);
-    type = object_store->non_nullable_string_type();
-    type_args.SetTypeAt(0, type);
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_non_nullable_string(type_args);
 
     type_args = TypeArguments::New(2);
     type = object_store->string_type();
@@ -2318,18 +2269,6 @@
     type_args.SetTypeAt(1, Object::dynamic_type());
     type_args = type_args.Canonicalize(thread, nullptr);
     object_store->set_type_argument_string_dynamic(type_args);
-    type_args = TypeArguments::New(2);
-    type = object_store->legacy_string_type();
-    type_args.SetTypeAt(0, type);
-    type_args.SetTypeAt(1, Object::dynamic_type());
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_legacy_string_dynamic(type_args);
-    type_args = TypeArguments::New(2);
-    type = object_store->non_nullable_string_type();
-    type_args.SetTypeAt(0, type);
-    type_args.SetTypeAt(1, Object::dynamic_type());
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_non_nullable_string_dynamic(type_args);
 
     type_args = TypeArguments::New(2);
     type = object_store->string_type();
@@ -2337,19 +2276,6 @@
     type_args.SetTypeAt(1, type);
     type_args = type_args.Canonicalize(thread, nullptr);
     object_store->set_type_argument_string_string(type_args);
-    type_args = TypeArguments::New(2);
-    type = object_store->legacy_string_type();
-    type_args.SetTypeAt(0, type);
-    type_args.SetTypeAt(1, type);
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_legacy_string_legacy_string(type_args);
-    type_args = TypeArguments::New(2);
-    type = object_store->non_nullable_string_type();
-    type_args.SetTypeAt(0, type);
-    type_args.SetTypeAt(1, type);
-    type_args = type_args.Canonicalize(thread, nullptr);
-    object_store->set_type_argument_non_nullable_string_non_nullable_string(
-        type_args);
 
     lib = Library::LookupLibrary(thread, Symbols::DartFfi());
     if (lib.IsNull()) {
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 85a4265..530240b 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -68,13 +68,9 @@
   RW(Class, never_class)                                                       \
   RW(Type, never_type)                                                         \
   RW(Type, function_type)                                                      \
-  RW(Type, legacy_function_type)                                               \
-  RW(Type, non_nullable_function_type)                                         \
   RW(Type, type_type)                                                          \
   RW(Class, closure_class)                                                     \
   RW(Type, number_type)                                                        \
-  RW(Type, legacy_number_type)                                                 \
-  RW(Type, non_nullable_number_type)                                           \
   RW(Type, int_type)                                                           \
   RW(Type, legacy_int_type)                                                    \
   RW(Type, non_nullable_int_type)                                              \
@@ -83,38 +79,23 @@
   RW(Type, int64_type)                                                         \
   RW(Class, smi_class)                                                         \
   RW(Type, smi_type)                                                           \
-  RW(Type, legacy_smi_type)                                                    \
-  RW(Type, non_nullable_smi_type)                                              \
   RW(Class, mint_class)                                                        \
   RW(Type, mint_type)                                                          \
-  RW(Type, legacy_mint_type)                                                   \
-  RW(Type, non_nullable_mint_type)                                             \
   RW(Class, double_class)                                                      \
   RW(Type, double_type)                                                        \
-  RW(Type, legacy_double_type)                                                 \
-  RW(Type, non_nullable_double_type)                                           \
   RW(Type, nullable_double_type)                                               \
   RW(Type, float32x4_type)                                                     \
   RW(Type, int32x4_type)                                                       \
   RW(Type, float64x2_type)                                                     \
   RW(Type, string_type)                                                        \
   RW(Type, legacy_string_type)                                                 \
-  RW(Type, non_nullable_string_type)                                           \
   RW(TypeArguments, type_argument_int)                                         \
   RW(TypeArguments, type_argument_legacy_int)                                  \
-  RW(TypeArguments, type_argument_non_nullable_int)                            \
   RW(TypeArguments, type_argument_double)                                      \
-  RW(TypeArguments, type_argument_legacy_double)                               \
-  RW(TypeArguments, type_argument_non_nullable_double)                         \
   RW(TypeArguments, type_argument_string)                                      \
   RW(TypeArguments, type_argument_legacy_string)                               \
-  RW(TypeArguments, type_argument_non_nullable_string)                         \
   RW(TypeArguments, type_argument_string_dynamic)                              \
-  RW(TypeArguments, type_argument_legacy_string_dynamic)                       \
-  RW(TypeArguments, type_argument_non_nullable_string_dynamic)                 \
   RW(TypeArguments, type_argument_string_string)                               \
-  RW(TypeArguments, type_argument_legacy_string_legacy_string)                 \
-  RW(TypeArguments, type_argument_non_nullable_string_non_nullable_string)     \
   RW(Class, compiletime_error_class)                                           \
   RW(Class, pragma_class)                                                      \
   RW(Field, pragma_name)                                                       \
@@ -126,13 +107,9 @@
   RW(Class, external_one_byte_string_class)                                    \
   RW(Class, external_two_byte_string_class)                                    \
   RW(Type, bool_type)                                                          \
-  RW(Type, legacy_bool_type)                                                   \
-  RW(Type, non_nullable_bool_type)                                             \
   RW(Class, bool_class)                                                        \
   RW(Class, array_class)                                                       \
   RW(Type, array_type)                                                         \
-  RW(Type, legacy_array_type)                                                  \
-  RW(Type, non_nullable_array_type)                                            \
   RW(Class, immutable_array_class)                                             \
   RW(Class, growable_object_array_class)                                       \
   RW(Class, linked_hash_map_class)                                             \
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 2d8b2a5..f1394f7 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -185,8 +185,10 @@
                                      intptr_t samples_per_block) {
   const intptr_t size = Utils::RoundUp(
       blocks * samples_per_block * sizeof(Sample), VirtualMemory::PageSize());
-  const bool kNotExecutable = false;
-  memory_ = VirtualMemory::Allocate(size, kNotExecutable, "dart-profiler");
+  const bool executable = false;
+  const bool compressed = false;
+  memory_ =
+      VirtualMemory::Allocate(size, executable, compressed, "dart-profiler");
   if (memory_ == NULL) {
     OUT_OF_MEMORY();
   }
@@ -341,8 +343,10 @@
 AllocationSampleBuffer::AllocationSampleBuffer(intptr_t capacity) {
   const intptr_t size =
       Utils::RoundUp(capacity * sizeof(Sample), VirtualMemory::PageSize());
-  const bool kNotExecutable = false;
-  memory_ = VirtualMemory::Allocate(size, kNotExecutable, "dart-profiler");
+  const bool executable = false;
+  const bool compressed = false;
+  memory_ =
+      VirtualMemory::Allocate(size, executable, compressed, "dart-profiler");
   if (memory_ == NULL) {
     OUT_OF_MEMORY();
   }
diff --git a/runtime/vm/regexp_interpreter.cc b/runtime/vm/regexp_interpreter.cc
index 610ac03..e8b3a47 100644
--- a/runtime/vm/regexp_interpreter.cc
+++ b/runtime/vm/regexp_interpreter.cc
@@ -143,8 +143,10 @@
     // https://github.com/flutter/flutter/issues/29007 for examples.
     // So intead we directly ask OS to provide us memory.
     if (memory_ == nullptr) {
+      const bool executable = false;
+      const bool compressed = false;
       memory_ = std::unique_ptr<VirtualMemory>(VirtualMemory::Allocate(
-          sizeof(intptr_t) * kBacktrackStackSize, /*is_executable=*/false,
+          sizeof(intptr_t) * kBacktrackStackSize, executable, compressed,
           "regexp-backtrack-stack"));
     }
   }
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 108213c..b3be100 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -301,9 +301,22 @@
   Exceptions::ThrowArgumentError(value);
 }
 
-DEFINE_RUNTIME_ENTRY(DoubleToInteger, 0) {
+DEFINE_RUNTIME_ENTRY(DoubleToInteger, 1) {
   // Unboxed value is passed through a dedicated slot in Thread.
-  const double val = arguments.thread()->unboxed_double_runtime_arg();
+  double val = arguments.thread()->unboxed_double_runtime_arg();
+  const Smi& recognized_kind = Smi::CheckedHandle(zone, arguments.ArgAt(0));
+  switch (recognized_kind.Value()) {
+    case MethodRecognizer::kDoubleToInteger:
+      break;
+    case MethodRecognizer::kDoubleFloorToInt:
+      val = floor(val);
+      break;
+    case MethodRecognizer::kDoubleCeilToInt:
+      val = ceil(val);
+      break;
+    default:
+      UNREACHABLE();
+  }
   arguments.SetReturn(Integer::Handle(zone, DoubleToInteger(zone, val)));
 }
 
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index f62ce3bf..b3c53a8 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -3350,11 +3350,24 @@
       const int64_t rn_val = get_register(rn, R31IsZR);
       set_vregisterd(vd, 0, rn_val);
       set_vregisterd(vd, 1, 0);
-    } else if (instr->Bits(16, 5) == 24) {
-      // Format(instr, "fcvtzds'sf 'rd, 'vn");
+    } else if ((instr->Bits(16, 5) == 8) || (instr->Bits(16, 5) == 16) ||
+               (instr->Bits(16, 5) == 24)) {
       const intptr_t max = instr->Bit(31) == 1 ? INT64_MAX : INT32_MAX;
       const intptr_t min = instr->Bit(31) == 1 ? INT64_MIN : INT32_MIN;
-      const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
+      double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
+      switch (instr->Bits(16, 5)) {
+        case 8:
+          // Format(instr, "fcvtps'sf 'rd, 'vn");
+          vn_val = ceil(vn_val);
+          break;
+        case 16:
+          // Format(instr, "fcvtms'sf 'rd, 'vn");
+          vn_val = floor(vn_val);
+          break;
+        case 24:
+          // Format(instr, "fcvtzs'sf 'rd, 'vn");
+          break;
+      }
       int64_t result;
       if (vn_val >= static_cast<double>(max)) {
         result = max;
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index fc74cf2..432b89f 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -4,6 +4,7 @@
 
 #include "vm/thread.h"
 
+#include "vm/cpu.h"
 #include "vm/dart_api_state.h"
 #include "vm/growable_array.h"
 #include "vm/heap/safepoint.h"
@@ -83,6 +84,8 @@
       ffi_callback_code_(GrowableObjectArray::null()),
       ffi_callback_stack_return_(TypedData::null()),
       api_top_scope_(NULL),
+      double_truncate_round_supported_(
+          TargetCPUFeatures::double_truncate_round_supported() ? 1 : 0),
       task_kind_(kUnknownTask),
       dart_stream_(NULL),
       thread_lock_(),
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 8c2aea4..d5f56ee 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -445,6 +445,10 @@
   void EnterApiScope();
   void ExitApiScope();
 
+  static intptr_t double_truncate_round_supported_offset() {
+    return OFFSET_OF(Thread, double_truncate_round_supported_);
+  }
+
   // The isolate that this thread is operating on, or nullptr if none.
   Isolate* isolate() const { return isolate_; }
   static intptr_t isolate_offset() { return OFFSET_OF(Thread, isolate_); }
@@ -1088,6 +1092,7 @@
   // JumpToExceptionHandler state:
   ObjectPtr active_exception_;
   ObjectPtr active_stacktrace_;
+
   ObjectPoolPtr global_object_pool_;
   uword resume_pc_;
   uword saved_shadow_call_stack_ = 0;
@@ -1097,6 +1102,7 @@
   TypedDataPtr ffi_callback_stack_return_;
   uword exit_through_ffi_ = 0;
   ApiLocalScope* api_top_scope_;
+  uint8_t double_truncate_round_supported_;
 
   // ---- End accessed from generated code. ----
 
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 9c14b8b..7b0ed2c 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -1122,8 +1122,10 @@
 
   intptr_t size = Utils::RoundUp(num_blocks_ * sizeof(TimelineEventBlock),
                                  VirtualMemory::PageSize());
-  const bool kNotExecutable = false;
-  memory_ = VirtualMemory::Allocate(size, kNotExecutable, "dart-timeline");
+  const bool executable = false;
+  const bool compressed = false;
+  memory_ =
+      VirtualMemory::Allocate(size, executable, compressed, "dart-timeline");
   if (memory_ == NULL) {
     OUT_OF_MEMORY();
   }
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index dc9b2d7..883bc74 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -50,12 +50,15 @@
   // the requested size cannot be allocated, NULL is returned.
   static VirtualMemory* Allocate(intptr_t size,
                                  bool is_executable,
+                                 bool is_compressed,
                                  const char* name) {
-    return AllocateAligned(size, PageSize(), is_executable, name);
+    return AllocateAligned(size, PageSize(), is_executable, is_compressed,
+                           name);
   }
   static VirtualMemory* AllocateAligned(intptr_t size,
                                         intptr_t alignment,
                                         bool is_executable,
+                                        bool is_compressed,
                                         const char* name);
 
   // Returns the cached page size. Use only if Init() has been called.
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index 3eb51e8..49f9216 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -112,6 +112,7 @@
 VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                               intptr_t alignment,
                                               bool is_executable,
+                                              bool is_compressed,
                                               const char* name) {
   // When FLAG_write_protect_code is active, code memory (indicated by
   // is_executable = true) is allocated as non-executable and later
@@ -134,8 +135,13 @@
   ASSERT((ZX_VM_ALIGN_1KB <= align_flag) && (align_flag <= ZX_VM_ALIGN_4GB));
 
 #if defined(DART_COMPRESSED_POINTERS)
-  zx_handle_t vmar =
-      is_executable ? zx_vmar_root_self() : compressed_heap_vmar_;
+  zx_handle_t vmar;
+  if (is_compressed) {
+    RELEASE_ASSERT(!is_executable);
+    vmar = compressed_heap_vmar_;
+  } else {
+    vmar = zx_vmar_root_self();
+  }
 #else
   zx_handle_t vmar = zx_vmar_root_self();
 #endif  // defined(DART_COMPRESSED_POINTERS)
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 0134610..4eaa832 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -160,7 +160,10 @@
   if (FLAG_dual_map_code) {
     intptr_t size = PageSize();
     intptr_t alignment = kOldPageSize;
-    VirtualMemory* vm = AllocateAligned(size, alignment, true, "memfd-test");
+    bool executable = true;
+    bool compressed = false;
+    VirtualMemory* vm =
+        AllocateAligned(size, alignment, executable, compressed, "memfd-test");
     if (vm == nullptr) {
       LOG_INFO("memfd_create not supported; disabling dual mapping of code.\n");
       FLAG_dual_map_code = false;
@@ -280,6 +283,7 @@
 VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                               intptr_t alignment,
                                               bool is_executable,
+                                              bool is_compressed,
                                               const char* name) {
   // When FLAG_write_protect_code is active, code memory (indicated by
   // is_executable = true) is allocated as non-executable and later
@@ -293,7 +297,8 @@
   ASSERT(name != nullptr);
 
 #if defined(DART_COMPRESSED_POINTERS)
-  if (!is_executable) {
+  if (is_compressed) {
+    RELEASE_ASSERT(!is_executable);
     MemoryRegion region =
         VirtualMemoryCompressedHeap::Allocate(size, alignment);
     if (region.pointer() == nullptr) {
diff --git a/runtime/vm/virtual_memory_test.cc b/runtime/vm/virtual_memory_test.cc
index 471c683..c343961 100644
--- a/runtime/vm/virtual_memory_test.cc
+++ b/runtime/vm/virtual_memory_test.cc
@@ -22,17 +22,12 @@
 VM_UNIT_TEST_CASE(AllocateVirtualMemory) {
   const intptr_t kVirtualMemoryBlockSize = 64 * KB;
   VirtualMemory* vm =
-      VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, "test");
+      VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, false, "test");
   EXPECT(vm != NULL);
   EXPECT(vm->address() != NULL);
   EXPECT_EQ(vm->start(), reinterpret_cast<uword>(vm->address()));
-#if defined(DART_COMPRESSED_POINTERS)
-  EXPECT_EQ(kCompressedHeapPageSize, vm->size());
-  EXPECT_EQ(vm->start() + kCompressedHeapPageSize, vm->end());
-#else
   EXPECT_EQ(kVirtualMemoryBlockSize, vm->size());
   EXPECT_EQ(vm->start() + kVirtualMemoryBlockSize, vm->end());
-#endif  // defined(DART_COMPRESSED_POINTERS)
   EXPECT(vm->Contains(vm->start()));
   EXPECT(vm->Contains(vm->start() + 1));
   EXPECT(vm->Contains(vm->start() + kVirtualMemoryBlockSize - 1));
@@ -63,7 +58,7 @@
   intptr_t kIterations = kHeapPageSize / kVirtualPageSize;
   for (intptr_t i = 0; i < kIterations; i++) {
     VirtualMemory* vm = VirtualMemory::AllocateAligned(
-        kHeapPageSize, kHeapPageSize, false, "test");
+        kHeapPageSize, kHeapPageSize, false, false, "test");
     EXPECT(Utils::IsAligned(vm->start(), kHeapPageSize));
     EXPECT_EQ(kHeapPageSize, vm->size());
     delete vm;
@@ -76,19 +71,19 @@
   const intptr_t kIterations = 900;  // Enough to exhaust 32-bit address space.
   for (intptr_t i = 0; i < kIterations; ++i) {
     VirtualMemory* vm =
-        VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, "test");
+        VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, false, "test");
     delete vm;
   }
   // Check that truncation does not introduce leaks.
   for (intptr_t i = 0; i < kIterations; ++i) {
     VirtualMemory* vm =
-        VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, "test");
+        VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, false, "test");
     vm->Truncate(kVirtualMemoryBlockSize / 2);
     delete vm;
   }
   for (intptr_t i = 0; i < kIterations; ++i) {
     VirtualMemory* vm =
-        VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, "test");
+        VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, false, "test");
     vm->Truncate(0);
     delete vm;
   }
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index 67f1f63..f7b64f5 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -82,6 +82,7 @@
 VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                               intptr_t alignment,
                                               bool is_executable,
+                                              bool is_compressed,
                                               const char* name) {
   // When FLAG_write_protect_code is active, code memory (indicated by
   // is_executable = true) is allocated as non-executable and later
@@ -91,7 +92,8 @@
   ASSERT(Utils::IsAligned(alignment, PageSize()));
 
 #if defined(DART_COMPRESSED_POINTERS)
-  if (!is_executable) {
+  if (is_compressed) {
+    RELEASE_ASSERT(!is_executable);
     MemoryRegion region =
         VirtualMemoryCompressedHeap::Allocate(size, alignment);
     if (region.pointer() == nullptr) {
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 5fa1efc..763617f 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -87,7 +87,9 @@
     }
   }
   if (memory == nullptr) {
-    memory = VirtualMemory::Allocate(size, false, "dart-zone");
+    bool executable = false;
+    bool compressed = false;
+    memory = VirtualMemory::Allocate(size, executable, compressed, "dart-zone");
     total_size_.fetch_add(size);
   }
   if (memory == nullptr) {
diff --git a/runtime/vm/zone_test.cc b/runtime/vm/zone_test.cc
index e52b940..2f691a9 100644
--- a/runtime/vm/zone_test.cc
+++ b/runtime/vm/zone_test.cc
@@ -242,4 +242,18 @@
 #endif  // !defined(PRODUCT)
 }
 
+#if defined(DART_COMPRESSED_POINTERS)
+ISOLATE_UNIT_TEST_CASE(ZonesNotLimitedByCompressedHeap) {
+  StackZone stack_zone(Thread::Current());
+  Zone* zone = stack_zone.GetZone();
+
+  size_t total = 0;
+  while (total <= (4u * GB)) {
+    size_t chunk_size = 512u * MB;
+    zone->AllocUnsafe(chunk_size);
+    total += chunk_size;
+  }
+}
+#endif  // defined(DART_COMPRESSED_POINTERS)
+
 }  // namespace dart
diff --git a/sdk/lib/_internal/vm/lib/double.dart b/sdk/lib/_internal/vm/lib/double.dart
index 26406d3..7559150 100644
--- a/sdk/lib/_internal/vm/lib/double.dart
+++ b/sdk/lib/_internal/vm/lib/double.dart
@@ -178,9 +178,14 @@
   }
 
   int round() => roundToDouble().toInt();
+  int truncate() => toInt();
+
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
   int floor() => floorToDouble().toInt();
+  @pragma("vm:recognized", "other")
+  @pragma("vm:prefer-inline")
   int ceil() => ceilToDouble().toInt();
-  int truncate() => truncateToDouble().toInt();
 
   @pragma("vm:recognized", "other")
   @pragma("vm:prefer-inline")
diff --git a/tests/language/constructor/explicit_instantiation_syntax_test.dart b/tests/language/constructor/explicit_instantiation_syntax_test.dart
index 3b3ddd3..387da72 100644
--- a/tests/language/constructor/explicit_instantiation_syntax_test.dart
+++ b/tests/language/constructor/explicit_instantiation_syntax_test.dart
@@ -42,6 +42,7 @@
 void h(_1, [_2]) {}
 
 int i = 0;
+bool boolVar = true;
 
 class Test {
   var x;
@@ -108,16 +109,17 @@
 
     g(C<int, int> . named());
 
-    g(C<int, int> .. toString());
+    h(C<int, int> .. toString()); //# 13: syntax error
+    g((C<int, int>) .. toString());
 
-    h(C<int, int> ...); //# 13: syntax error
+    h(C<int, int> ...); //# 14: syntax error
 
-    h(C<int, int> ...?); //# 14: syntax error
+    h(C<int, int> ...?); //# 15: syntax error
 
-    h(C<int, int> / 1); //# 15: syntax error
+    h(C<int, int> / 1); //# 16: syntax error
     g((C<int, int>) / 1);
 
-    g(C<int, int> /**/); //# 16: ok
+    g(C<int, int> /**/); //# 17: ok
     f(C<int, int> /**/ - 1);
 
     g(C<int, int> //
@@ -126,38 +128,38 @@
         -
         1);
 
-    h(C<int, int> /= 1); //# 17: syntax error
+    h(C<int, int> /= 1); //# 18: syntax error
 
     g({C<int, int> : 1});
 
-    C<int, int> ; //# 18: ok
+    C<int, int> ; //# 19: ok
 
-    h(C<int, int> < 1); //# 19: syntax error
+    h(C<int, int> < 1); //# 20: syntax error
     g((C<int, int>) < 1);
 
-    h(C<int, int> << 1); //# 20: syntax error
+    h(C<int, int> << 1); //# 21: syntax error
     g((C<int, int>) << 1);
 
-    h(C<int, int> <<= 1); //# 21: syntax error
+    h(C<int, int> <<= 1); //# 22: syntax error
 
-    h(C<int, int> <= 1); //# 22: syntax error
+    h(C<int, int> <= 1); //# 23: syntax error
     g((C<int, int>) <= 1);
 
-    h(C<int, int> = 1); //# 23: syntax error
+    h(C<int, int> = 1); //# 24: syntax error
 
     g(C<int, int> == 1);
 
-    h(C<int, int> =>); //# 24: syntax error
+    h(C<int, int> =>); //# 25: syntax error
 
     // The operator `>>` is a single token in the grammar.
-    h(C<int, int> > 1); //# 25: syntax error
+    h(C<int, int> > 1); //# 26: syntax error
     h((C<int, int>) > 1);
 
-    h(true + C<int, int> ? 1 : 1); //# 26: syntax error
+    h(true + C<int, int> ? 1 : 1); //# 27: syntax error
     g(true + (C<int, int>) ? 1 : 1);
 
-    g(C<int, int> ?. toString()); //# 27: syntax error
-    g((C<int, int>) ?. toString()); //# 28: static type warning
+    g(C<int, int> ?. toString()); //# 28: syntax error
+    g((boolVar ? null : C<int, int>) ?. toString());
 
     h(C<int, int> ?.. toString()); //# 29: syntax error
 
diff --git a/tests/language/operator/arithmetic_test.dart b/tests/language/operator/arithmetic_test.dart
index 7784f35..8661896 100644
--- a/tests/language/operator/arithmetic_test.dart
+++ b/tests/language/operator/arithmetic_test.dart
@@ -1,8 +1,11 @@
 // Copyright (c) 2012, 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.
+
 // Dart test program to test arithmetic operations.
+
 // VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+// VMOptions=--use_slow_path
 
 library arithmetic_test;
 
diff --git a/tests/language_2/operator/arithmetic_test.dart b/tests/language_2/operator/arithmetic_test.dart
index 966570a..9f1f74b 100644
--- a/tests/language_2/operator/arithmetic_test.dart
+++ b/tests/language_2/operator/arithmetic_test.dart
@@ -1,8 +1,11 @@
 // Copyright (c) 2012, 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.
+
 // Dart test program to test arithmetic operations.
+
 // VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+// VMOptions=--use_slow_path
 
 // @dart = 2.9
 
diff --git a/tools/VERSION b/tools/VERSION
index 570bc94..b94b4f1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 90
+PRERELEASE 91
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 0759d39..bb7ce34 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -2945,7 +2945,7 @@
             "create_sdk"
           ],
           "environment": {
-            "DART_GN_ARGS": "mac_use_goma_rbe=true"
+            "DART_GN_ARGS": "mac_use_goma_rbe=true dart_snapshot_kind=\"app-jit\""
           }
         },
         {