Version 3.2.0-207.0.dev

Merge 82ff34d7751741fceb9cd1420519c6286c4201ce into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec3fb09..5c5fe10 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -105,6 +105,9 @@
 - All `NativeCallable` constructors can now accept closures. Previously
   `NativeCallable`s had the same restrictions as `Pointer.fromFunction`, and
   could only create callbacks for static functions.
+- **Breaking change** [#53311][]: `NativeCallable.nativeFunction` now throws an
+  error if is called after the `NativeCallable` has already been `close`d. Calls
+  to `close` after the first are now ignored.
 
 #### `dart:io`
 
diff --git a/DEPS b/DEPS
index 8edb7c1..6cf954c 100644
--- a/DEPS
+++ b/DEPS
@@ -99,7 +99,7 @@
   "boringssl_gen_rev": "a468ba9fec3f59edf46a7db98caaca893e1e4d96",
   "boringssl_rev": "74646566e93de7551bfdfc5f49de7462f13d1d05",
   "browser-compat-data_tag": "ac8cae697014da1ff7124fba33b0b4245cc6cd1b", # v1.0.22
-  "devtools_rev": "61d618843c76b328b1382193378d52eb9f3def04",
+  "devtools_rev": "11ec4ae1036408018143b58d80d6feadbee56a6c",
   "icu_rev": "81d656878ec611cb0b42d52c82e9dae93920d9ba",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "libcxx_rev": "44079a4cc04cdeffb9cfe8067bfb3c276fb2bab0",
diff --git a/pkg/_fe_analyzer_shared/lib/src/field_promotability.dart b/pkg/_fe_analyzer_shared/lib/src/field_promotability.dart
index 01295a1..c93684a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/field_promotability.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/field_promotability.dart
@@ -5,20 +5,68 @@
 import 'package:_fe_analyzer_shared/src/util/dependency_walker.dart';
 
 /// Information about a [Class] that is necessary for computing the set of
-/// private `noSuchMethod` getters the compiler will generate.
+/// private `noSuchMethod` forwarding getters the compiler will generate.
+///
+/// The type parameter [Class] has the same meaning as in [FieldPromotability].
 class ClassInfo<Class extends Object> {
-  /// The [_InterfaceNode] for the [Class].
   final _InterfaceNode<Class> _interfaceNode;
 
-  /// The [_ImplementedNode] for the [Class].
   final _ImplementedNode<Class> _implementedNode;
 
   ClassInfo(this._interfaceNode, this._implementedNode);
+
+  Class get _class => _interfaceNode._class;
+}
+
+/// Reasons why property accesses having a given field name are non-promotable.
+///
+/// This class is part of the data structure output by
+/// [FieldPromotability.computeNonPromotabilityInfo].
+///
+/// The type parameters [Class], [Field], and [Getter] have the same meaning as
+/// in [FieldPromotability].
+class FieldNameNonPromotabilityInfo<Class extends Object, Field, Getter> {
+  /// The fields with the given name that are not promotable (either because
+  /// they are not final or because they are external).
+  ///
+  /// (This list is initially empty and
+  /// [FieldPromotability.computeNonPromotabilityInfo] accumulates entries into
+  /// it.)
+  final List<Field> interferingFields = [];
+
+  /// The explicit concrete getters with the given name.
+  ///
+  /// (This list is initially empty and
+  /// [FieldPromotability.computeNonPromotabilityInfo] accumulates entries into
+  /// it.)
+  final List<Getter> interferingGetters = [];
+
+  /// The classes that implicitly forward a getter with the given name to
+  /// `noSuchMethod`.
+  ///
+  /// The purpose of this list is so that the client can generate error messages
+  /// that clarify to the user that field promotion was not possible due to
+  /// `noSuchMethod` forwarding getters. It is a list of [Class] rather than
+  /// [Getter] because `noSuchMethod` forwarding getters are always implicit;
+  /// hence the error messages should be associated with the class.
+  ///
+  /// (This list is initially empty and
+  /// [FieldPromotability.computeNonPromotabilityInfo] accumulates entries into
+  /// it.)
+  final List<Class> interferingNsmClasses = [];
+
+  FieldNameNonPromotabilityInfo._();
 }
 
 /// This class examines all the [Class]es in a library and determines which
 /// fields are promotable within that library.
 ///
+/// The type parameters [Class], [Field] and [Getter] should be the data
+/// structures used by the client to represent classes, fields, and getters in
+/// the user's program. This class treats these types abstractly, so that each
+/// concrete Dart implementation can use their own representation of the user's
+/// code.
+///
 /// Note: the term [Class] is used in a general sense here; it can represent any
 /// class, mixin, or enum declared in the user's program.
 ///
@@ -91,10 +139,12 @@
 /// stable in the sense of always being identical, they will nonetheless always
 /// have the same runtime type. Hence, we can completely ignore methods when
 /// computing which fields in the library are promotable.
-abstract class FieldPromotability<Class extends Object> {
-  /// The set of field names in the library that have been determined to be
-  /// unsafe to promote.
-  final Set<String> _unpromotableFieldNames = {};
+abstract class FieldPromotability<Class extends Object, Field, Getter> {
+  /// Map whose keys are the field names in the library that have been
+  /// determined to be unsafe to promote, and whose values are an instance of
+  /// `FieldNameNonPromotabilityInfo` describing why.
+  final Map<String, FieldNameNonPromotabilityInfo<Class, Field, Getter>>
+      _nonPromotabilityInfo = {};
 
   /// Map from a [Class] object to the [_ImplementedNode] that records the names
   /// of concrete fields and getters declared in or inherited by the [Class].
@@ -125,24 +175,25 @@
     return classInfo;
   }
 
-  /// Records that the [Class] described by [classInfo] contains a non-synthetic
-  /// instance field with the given [name].
+  /// Records that the [Class] described by [classInfo] contains non-synthetic
+  /// instance [field] with the given [name].
   ///
   /// [isFinal] indicates whether the field is a final field. [isAbstract]
   /// indicates whether the field is abstract. [isExternal] indicates whether
   /// the field is external.
   ///
-  /// A return value of `true` indicates that this field *might* wind up being
-  /// promotable; a return value of `false` indicates that it *definitely* isn't
-  /// promotable.
-  bool addField(ClassInfo<Class> classInfo, String name,
+  /// A return value of `null` indicates that this field *might* wind up being
+  /// promotable; any other return value indicates the reason why it
+  /// *definitely* isn't promotable.
+  PropertyNonPromotabilityReason? addField(
+      ClassInfo<Class> classInfo, Field field, String name,
       {required bool isFinal,
       required bool isAbstract,
       required bool isExternal}) {
     // Public fields are never promotable, so we may safely ignore fields with
     // public names.
     if (!name.startsWith('_')) {
-      return false;
+      return PropertyNonPromotabilityReason.isNotPrivate;
     }
 
     // Record the field name for later use in computation of `noSuchMethod`
@@ -155,20 +206,27 @@
     if (isExternal || !isFinal) {
       // The field isn't promotable, nor is any other field in the library with
       // the same name.
-      _unpromotableFieldNames.add(name);
-      return false;
+      _fieldNonPromoInfo(name).interferingFields.add(field);
+      return isExternal
+          ? PropertyNonPromotabilityReason.isExternal
+          : PropertyNonPromotabilityReason.isNotFinal;
     }
 
     // The field is final and not external, so it might wind up being
     // promotable.
-    return true;
+    return null;
   }
 
   /// Records that the [Class] described by [classInfo] contains a non-synthetic
-  /// instance getter with the given [name].
+  /// instance [getter] with the given [name].
   ///
   /// [isAbstract] indicates whether the getter is abstract.
-  void addGetter(ClassInfo<Class> classInfo, String name,
+  ///
+  /// Note that unlike [addField], this method does not return a
+  /// [PropertyNonPromotabilityReason]. The caller may safely assume that the
+  /// reason that getters are not promotable is
+  /// [PropertyNonPromotabilityReason.isNotField].
+  void addGetter(ClassInfo<Class> classInfo, Getter getter, String name,
       {required bool isAbstract}) {
     // Public fields are never promotable, so we may safely ignore getters with
     // public names.
@@ -183,16 +241,17 @@
       classInfo._implementedNode._directNames.add(name);
 
       // The getter is concrete, so no fields with the same name are promotable.
-      _unpromotableFieldNames.add(name);
+      _fieldNonPromoInfo(name).interferingGetters.add(getter);
     }
   }
 
   /// Computes the set of private field names which are not safe to promote in
-  /// the library.
+  /// the library, along with the reasons why.
   ///
   /// The client should call this method once after all [Class]es, fields, and
   /// getters have been recorded using [addClass], [addField], and [addGetter].
-  Set<String> computeUnpromotablePrivateFieldNames() {
+  Map<String, FieldNameNonPromotabilityInfo<Class, Field, Getter>>
+      computeNonPromotabilityInfo() {
     // The names of private non-final fields and private getters have already
     // been added to [_unpromotableFieldNames] by [addField] and [addGetter]. So
     // all that remains to do is figure out which field names are unpromotable
@@ -217,17 +276,17 @@
       implementedWalker.walk(implementedNode);
       Set<String> implementedNames = implementedNode._transitiveNames!;
 
-      // `noSuchMethod` getters will be generated for getters that are in the
-      // interface, but not actually implemented; consequently, fields with
-      // these names are not safe to promote.
+      // `noSuchMethod`-forwarding getters will be generated for getters that
+      // are in the interface, but not actually implemented; consequently,
+      // fields with these names are not safe to promote.
       for (String name in interfaceNames) {
         if (!implementedNames.contains(name)) {
-          _unpromotableFieldNames.add(name);
+          _fieldNonPromoInfo(name).interferingNsmClasses.add(info._class);
         }
       }
     }
 
-    return _unpromotableFieldNames;
+    return _nonPromotabilityInfo;
   }
 
   /// Returns an iterable of the direct superclasses of [class_]. If
@@ -244,6 +303,12 @@
   Iterable<Class> getSuperclasses(Class class_,
       {required bool ignoreImplements});
 
+  /// Gets the [FieldNameNonPromotabilityInfo] object corresponding to [name]
+  /// from [_nonPromotabilityInfo], creating it if necessary.
+  FieldNameNonPromotabilityInfo<Class, Field, Getter> _fieldNonPromoInfo(
+          String name) =>
+      _nonPromotabilityInfo.putIfAbsent(name, FieldNameNonPromotabilityInfo._);
+
   /// Gets or creates the [_ImplementedNode] for [class_].
   _ImplementedNode<Class> _getImplementedNode(Class class_) =>
       _implementedNodes[class_] ??= new _ImplementedNode<Class>(this, class_);
@@ -253,6 +318,38 @@
       _interfaceNodes[class_] ??= new _InterfaceNode<Class>(this, class_);
 }
 
+/// Possible reasons why a field property may not be promotable.
+///
+/// Some of these reasons are distinguished by [FieldPromotability.addField];
+/// others must be distinguished by the client.
+enum PropertyNonPromotabilityReason {
+  /// The property is not promotable because field promotion is not enabled for
+  /// the enclosing library.
+  isNotEnabled,
+
+  /// The property is not promotable because it's not a field (it's either a
+  /// getter or a tear-off of a method).
+  isNotField,
+
+  /// The property is not promotable because its name is public.
+  isNotPrivate,
+
+  /// The property is not promotable because it's an external field.
+  isExternal,
+
+  /// The property is not promotable because it's a non-final field.
+  isNotFinal,
+
+  /// The property is not promotable because there's an explicit getter,
+  /// implicit noSuchMethod forwarding getter, or non-promotable field elsewhere
+  /// in the library, and that getter or field has the same name.
+  ///
+  /// Further information about what precise class members interfered with
+  /// promotion may be found in the map returned by
+  /// [FieldPromotability.computeNonPromotabilityInfo].
+  isInterferedWith,
+}
+
 /// Dependency walker that traverses the graph of a class's type hierarchy,
 /// gathering the transitive closure of field and getter names.
 ///
@@ -339,7 +436,7 @@
 /// getters the compiler will generate.
 abstract class _Node<Class extends Object> extends Node<_Node<Class>> {
   /// A reference back to the [FieldPromotability] object.
-  final FieldPromotability<Class> _fieldPromotability;
+  final FieldPromotability<Class, Object?, Object?> _fieldPromotability;
 
   /// The [Class] represented by this node.
   final Class _class;
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 8f4e692..4150ebb 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -4,6 +4,7 @@
 
 import 'package:meta/meta.dart';
 
+import '../field_promotability.dart';
 import '../type_inference/assigned_variables.dart';
 import '../type_inference/promotion_key_store.dart';
 import '../type_inference/type_operations.dart';
@@ -2778,11 +2779,10 @@
   /// The expression in question is a property get. It couldn't be promoted
   /// because promotion of property gets is not supported.
   ///
-  /// In Dart 3.2, this link will no longer be used, but it was used in Dart
-  /// versions 3.1 and earlier (so the documentation web site should continue to
-  /// support it until most users have upgraded to 3.2 or later).
-  ///
-  /// TODO(paulberry): once this link is no longer used, mark it `@deprecated`.
+  /// This link is no longer used, but it was used in Dart versions 3.1 and
+  /// earlier (so the documentation web site should continue to support it until
+  /// most users have upgraded to 3.2 or later).
+  @deprecated
   property('http://dart.dev/go/non-promo-property'),
 
   /// The expression in question is a reference to a field, but it couldn't be
@@ -2842,7 +2842,11 @@
   /// Link to documentation describing this non-promotion reason; this should be
   /// presented to the user as a source of additional information about the
   /// error.
-  NonPromotionDocumentationLink get documentationLink;
+  ///
+  /// In certain circumstances this link may be `null`, in which case the client
+  /// needs to supply a documentation link from the
+  /// [NonPromotionDocumentationLink] enum.
+  NonPromotionDocumentationLink? get documentationLink;
 
   /// Short text description of this non-promotion reason; intended for ID
   /// testing.
@@ -2869,11 +2873,30 @@
 /// Operations on types and variables, abstracted from concrete type interfaces.
 abstract class Operations<Variable extends Object, Type extends Object>
     implements TypeOperations<Type>, VariableOperations<Variable, Type> {
-  /// Determines whether the given property can be promoted.  [propertyMember]
-  /// will correspond to a `propertyMember` value passed to
+  /// Determines whether the given property can be promoted.
+  ///
+  /// [property] will correspond to a `propertyMember` value passed to
   /// [FlowAnalysis.promotedPropertyType], [FlowAnalysis.propertyGet], or
   /// [FlowAnalysis.pushPropertySubpattern].
   bool isPropertyPromotable(Object property);
+
+  /// Returns additional information about why a given property couldn't be
+  /// promoted. [propertyMember] will correspond to a `propertyMember` value
+  /// passed to [FlowAnalysis.promotedPropertyType], [FlowAnalysis.propertyGet],
+  /// or [FlowAnalysis.pushPropertySubpattern].
+  ///
+  /// This method is only called if a closure returned by
+  /// [FlowAnalysis.whyNotPromoted] is invoked, and the expression being queried
+  /// is a reference to a property that wasn't promoted; this typically means
+  /// that an error occurred and the client is attempting to produce a context
+  /// message to provide additional information about the error (i.e., that the
+  /// error happened due to failed promotion).
+  ///
+  /// The client may return `null` if it is unable to determine why [property]
+  /// was not promotable; if this happens, the closure returned by
+  /// [FlowAnalysis.whyNotPromoted] will yield an empty map (so the user won't
+  /// receive any context information).
+  PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(Object property);
 }
 
 /// Data structure describing the relationship among variables defined by
@@ -3531,11 +3554,27 @@
   /// the client as a convenience for ID testing.
   final Type staticType;
 
-  PropertyNotPromoted(this.propertyName, this.propertyMember, this.staticType);
+  /// The reason why the property isn't promotable.
+  final PropertyNonPromotabilityReason whyNotPromotable;
+
+  PropertyNotPromoted(this.propertyName, this.propertyMember, this.staticType,
+      this.whyNotPromotable);
 
   @override
-  NonPromotionDocumentationLink get documentationLink =>
-      NonPromotionDocumentationLink.property;
+  NonPromotionDocumentationLink? get documentationLink =>
+      switch (whyNotPromotable) {
+        PropertyNonPromotabilityReason.isNotEnabled =>
+          NonPromotionDocumentationLink.fieldPromotionUnavailable,
+        PropertyNonPromotabilityReason.isNotField =>
+          NonPromotionDocumentationLink.nonField,
+        PropertyNonPromotabilityReason.isNotPrivate =>
+          NonPromotionDocumentationLink.publicField,
+        PropertyNonPromotabilityReason.isExternal =>
+          NonPromotionDocumentationLink.externalField,
+        PropertyNonPromotabilityReason.isNotFinal =>
+          NonPromotionDocumentationLink.nonFinalField,
+        PropertyNonPromotabilityReason.isInterferedWith => null,
+      };
 
   @override
   String get shortName => 'propertyNotPromoted';
@@ -5609,30 +5648,38 @@
   Map<Type, NonPromotionReason> Function() _getNonPromotionReasons(
       _Reference<Type> reference, PromotionModel<Type>? currentPromotionInfo) {
     if (reference is _PropertyReference<Type>) {
-      _PropertySsaNode<Type>? ssaNode =
-          (reference.ssaNode as _PropertySsaNode<Type>).previousSsaNode;
-      List<List<Type>>? allPreviouslyPromotedTypes;
-      while (ssaNode != null) {
-        PromotionModel<Type> previousPromotionInfo =
-            _current.infoFor(this, ssaNode.promotionKey, ssaNode: ssaNode);
-        List<Type>? promotedTypes = previousPromotionInfo.promotedTypes;
-        if (promotedTypes != null) {
-          (allPreviouslyPromotedTypes ??= []).add(promotedTypes);
-        }
-        ssaNode = ssaNode.previousSsaNode;
-      }
-      if (allPreviouslyPromotedTypes != null) {
-        return () {
-          Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
-          for (List<Type> previouslyPromotedTypes
-              in allPreviouslyPromotedTypes!) {
-            for (Type type in previouslyPromotedTypes) {
-              result[type] = new PropertyNotPromoted(reference.propertyName,
-                  reference.propertyMember, reference._type);
+      Object? propertyMember = reference.propertyMember;
+      if (propertyMember != null) {
+        PropertyNonPromotabilityReason? whyNotPromotable =
+            operations.whyPropertyIsNotPromotable(propertyMember);
+        if (whyNotPromotable != null) {
+          _PropertySsaNode<Type>? ssaNode =
+              (reference.ssaNode as _PropertySsaNode<Type>).previousSsaNode;
+          List<List<Type>>? allPreviouslyPromotedTypes;
+          while (ssaNode != null) {
+            PromotionModel<Type> previousPromotionInfo =
+                _current.infoFor(this, ssaNode.promotionKey, ssaNode: ssaNode);
+            List<Type>? promotedTypes = previousPromotionInfo.promotedTypes;
+            if (promotedTypes != null) {
+              (allPreviouslyPromotedTypes ??= []).add(promotedTypes);
             }
+            ssaNode = ssaNode.previousSsaNode;
           }
-          return result;
-        };
+          if (allPreviouslyPromotedTypes != null) {
+            return () {
+              Map<Type, NonPromotionReason> result =
+                  <Type, NonPromotionReason>{};
+              for (List<Type> previouslyPromotedTypes
+                  in allPreviouslyPromotedTypes!) {
+                for (Type type in previouslyPromotedTypes) {
+                  result[type] = new PropertyNotPromoted(reference.propertyName,
+                      propertyMember, reference._type, whyNotPromotable);
+                }
+              }
+              return result;
+            };
+          }
+        }
       }
     } else if (currentPromotionInfo != null) {
       Variable? variable =
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index d1d328f..cd4faf6 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -5318,29 +5318,160 @@
     correctionMessage: r"""Try removing 'this.'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name, String string)>
-    templateFieldNotPromoted =
-    const Template<Message Function(String name, String string)>(
-        "FieldNotPromoted",
-        problemMessageTemplate:
-            r"""'#name' refers to a property so it couldn't be promoted.""",
-        correctionMessageTemplate: r"""See #string""",
-        withArguments: _withArgumentsFieldNotPromoted);
+const Template<
+    Message Function(
+        String name,
+        String
+            string)> templateFieldNotPromotedBecauseExternal = const Template<
+        Message Function(String name, String string)>(
+    "FieldNotPromotedBecauseExternal",
+    problemMessageTemplate:
+        r"""'#name' refers to an external field so it couldn't be promoted.""",
+    correctionMessageTemplate: r"""See #string""",
+    withArguments: _withArgumentsFieldNotPromotedBecauseExternal);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, String string)> codeFieldNotPromoted =
+const Code<Message Function(String name, String string)>
+    codeFieldNotPromotedBecauseExternal =
     const Code<Message Function(String name, String string)>(
-  "FieldNotPromoted",
+  "FieldNotPromotedBecauseExternal",
 );
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsFieldNotPromoted(String name, String string) {
+Message _withArgumentsFieldNotPromotedBecauseExternal(
+    String name, String string) {
   if (name.isEmpty) throw 'No name provided';
   name = demangleMixinApplicationName(name);
   if (string.isEmpty) throw 'No string provided';
-  return new Message(codeFieldNotPromoted,
+  return new Message(codeFieldNotPromotedBecauseExternal,
       problemMessage:
-          """'${name}' refers to a property so it couldn't be promoted.""",
+          """'${name}' refers to an external field so it couldn't be promoted.""",
+      correctionMessage: """See ${string}""",
+      arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String name,
+        String
+            string)> templateFieldNotPromotedBecauseNotEnabled = const Template<
+        Message Function(String name, String string)>(
+    "FieldNotPromotedBecauseNotEnabled",
+    problemMessageTemplate:
+        r"""'#name' refers to a field. It couldn't be promoted because field promotion is only available in Dart 3.2 and above.""",
+    correctionMessageTemplate: r"""See #string""",
+    withArguments: _withArgumentsFieldNotPromotedBecauseNotEnabled);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+    codeFieldNotPromotedBecauseNotEnabled =
+    const Code<Message Function(String name, String string)>(
+  "FieldNotPromotedBecauseNotEnabled",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFieldNotPromotedBecauseNotEnabled(
+    String name, String string) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
+  return new Message(codeFieldNotPromotedBecauseNotEnabled,
+      problemMessage:
+          """'${name}' refers to a field. It couldn't be promoted because field promotion is only available in Dart 3.2 and above.""",
+      correctionMessage: """See ${string}""",
+      arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name, String string)>
+    templateFieldNotPromotedBecauseNotField =
+    const Template<Message Function(String name, String string)>(
+        "FieldNotPromotedBecauseNotField",
+        problemMessageTemplate:
+            r"""'#name' refers to a getter so it couldn't be promoted.""",
+        correctionMessageTemplate: r"""See #string""",
+        withArguments: _withArgumentsFieldNotPromotedBecauseNotField);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+    codeFieldNotPromotedBecauseNotField =
+    const Code<Message Function(String name, String string)>(
+  "FieldNotPromotedBecauseNotField",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFieldNotPromotedBecauseNotField(
+    String name, String string) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
+  return new Message(codeFieldNotPromotedBecauseNotField,
+      problemMessage:
+          """'${name}' refers to a getter so it couldn't be promoted.""",
+      correctionMessage: """See ${string}""",
+      arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String name,
+        String
+            string)> templateFieldNotPromotedBecauseNotFinal = const Template<
+        Message Function(String name, String string)>(
+    "FieldNotPromotedBecauseNotFinal",
+    problemMessageTemplate:
+        r"""'#name' refers to a non-final field so it couldn't be promoted.""",
+    correctionMessageTemplate: r"""See #string""",
+    withArguments: _withArgumentsFieldNotPromotedBecauseNotFinal);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+    codeFieldNotPromotedBecauseNotFinal =
+    const Code<Message Function(String name, String string)>(
+  "FieldNotPromotedBecauseNotFinal",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFieldNotPromotedBecauseNotFinal(
+    String name, String string) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
+  return new Message(codeFieldNotPromotedBecauseNotFinal,
+      problemMessage:
+          """'${name}' refers to a non-final field so it couldn't be promoted.""",
+      correctionMessage: """See ${string}""",
+      arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name, String string)>
+    templateFieldNotPromotedBecauseNotPrivate =
+    const Template<Message Function(String name, String string)>(
+        "FieldNotPromotedBecauseNotPrivate",
+        problemMessageTemplate:
+            r"""'#name' refers to a public field so it couldn't be promoted.""",
+        correctionMessageTemplate: r"""See #string""",
+        withArguments: _withArgumentsFieldNotPromotedBecauseNotPrivate);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+    codeFieldNotPromotedBecauseNotPrivate =
+    const Code<Message Function(String name, String string)>(
+  "FieldNotPromotedBecauseNotPrivate",
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFieldNotPromotedBecauseNotPrivate(
+    String name, String string) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (string.isEmpty) throw 'No string provided';
+  return new Message(codeFieldNotPromotedBecauseNotPrivate,
+      problemMessage:
+          """'${name}' refers to a public field so it couldn't be promoted.""",
       correctionMessage: """See ${string}""",
       arguments: {'name': name, 'string': string});
 }
diff --git a/pkg/_fe_analyzer_shared/test/field_promotability_test.dart b/pkg/_fe_analyzer_shared/test/field_promotability_test.dart
index 062bde3..17de3dd 100644
--- a/pkg/_fe_analyzer_shared/test/field_promotability_test.dart
+++ b/pkg/_fe_analyzer_shared/test/field_promotability_test.dart
@@ -10,45 +10,94 @@
   test('final private field is promotable', () {
     var f = Field('_f', isFinal: true);
     var c = Class(fields: [f]);
-    check(_TestFieldPromotability().run([c])).unorderedEquals({});
-    check(f.isPossiblyPromotable).isTrue();
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo).isEmpty();
+    check(f.nonPromotabilityReason).equals(null);
   });
 
   test('final public field is not promotable', () {
     var f = Field('f', isFinal: true);
     var c = Class(fields: [f]);
-    // Note that the set returned by `_TestFieldPromotability.run` is just the
-    // set of *private* field names that are unpromotable, so even though `f`
-    // is not promotable, the returned set is empty.
-    check(_TestFieldPromotability().run([c])).unorderedEquals({});
-    check(f.isPossiblyPromotable).isFalse();
+    // Note that the map returned by `_TestFieldPromotability.run` is just the
+    // map of *private* field names that are unpromotable, so even though `f`
+    // is not promotable, the returned map is empty.
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo).isEmpty();
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isNotPrivate);
   });
 
   test('non-final private field is not promotable', () {
     var f = Field('_f');
     var c = Class(fields: [f]);
-    check(_TestFieldPromotability().run([c])).unorderedEquals({'_f'});
-    check(f.isPossiblyPromotable).isFalse();
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+    check(nonPromotabilityInfo['_f']!.interferingFields).unorderedEquals([f]);
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isNotFinal);
+  });
+
+  test('public dominates non-final', () {
+    // If a field is both public and non-final, the fact that it is public is
+    // used as the non-promotability reason.
+    var f = Field('f');
+    var c = Class(fields: [f]);
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo.keys).isEmpty;
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isNotPrivate);
   });
 
   test('external private final field is not promotable', () {
     var f = Field('_f', isFinal: true, isExternal: true);
     var c = Class(fields: [f]);
-    check(_TestFieldPromotability().run([c])).unorderedEquals({'_f'});
-    check(f.isPossiblyPromotable).isFalse();
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isExternal);
+  });
+
+  test('public dominates external', () {
+    // If a field is both public and external, the fact that it is public is
+    // used as the non-promotability reason.
+    var f = Field('f', isFinal: true, isExternal: true);
+    var c = Class(fields: [f]);
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo.keys).isEmpty;
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isNotPrivate);
+  });
+
+  test('external dominates non-final', () {
+    // If a field is both external and non-final, the fact that it is external
+    // is used as the non-promotability reason.
+    var f = Field('_f', isFinal: false, isExternal: true);
+    var c = Class(fields: [f]);
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c]);
+    check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isExternal);
   });
 
   group('concrete getter renders a private field non-promotable:', () {
     test('in a concrete class', () {
       var c = Class(fields: [Field('_f', isFinal: true)]);
-      var d = Class(getters: [Getter('_f')]);
-      check(_TestFieldPromotability().run([c, d])).unorderedEquals({'_f'});
+      var getter = Getter('_f');
+      var d = Class(getters: [getter]);
+      var nonPromotabilityInfo = _TestFieldPromotability().run([c, d]);
+      check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+      check(nonPromotabilityInfo['_f']!.interferingGetters)
+          .unorderedEquals([getter]);
     });
 
     test('in an abstract class', () {
       var c = Class(fields: [Field('_f', isFinal: true)]);
-      var d = Class(isAbstract: true, getters: [Getter('_f')]);
-      check(_TestFieldPromotability().run([c, d])).unorderedEquals({'_f'});
+      var getter = Getter('_f');
+      var d = Class(isAbstract: true, getters: [getter]);
+      var nonPromotabilityInfo = _TestFieldPromotability().run([c, d]);
+      check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+      check(nonPromotabilityInfo['_f']!.interferingGetters)
+          .unorderedEquals([getter]);
     });
   });
 
@@ -56,8 +105,9 @@
     var f = Field('_f', isFinal: true);
     var c = Class(fields: [f]);
     var d = Class(isAbstract: true, getters: [Getter('_f', isAbstract: true)]);
-    check(_TestFieldPromotability().run([c, d])).unorderedEquals({});
-    check(f.isPossiblyPromotable).isTrue();
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c, d]);
+    check(nonPromotabilityInfo).isEmpty();
+    check(f.nonPromotabilityReason).equals(null);
   });
 
   test('public concrete getter is ignored', () {
@@ -66,9 +116,11 @@
     var f = Field('f', isFinal: true);
     var c = Class(fields: [f]);
     var d = Class(getters: [Getter('f')]);
-    // Therefore the set returned by `_TestFieldPromotability.run` is empty.
-    check(_TestFieldPromotability().run([c, d])).unorderedEquals({});
-    check(f.isPossiblyPromotable).isFalse();
+    // Therefore the map returned by `_TestFieldPromotability.run` is empty.
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c, d]);
+    check(nonPromotabilityInfo).isEmpty();
+    check(f.nonPromotabilityReason)
+        .equals(PropertyNonPromotabilityReason.isNotPrivate);
   });
 
   group('unimplemented getter renders a field non-promotable:', () {
@@ -78,7 +130,10 @@
       var d =
           Class(isAbstract: true, getters: [Getter('_f', isAbstract: true)]);
       var e = Class(implements: [d]);
-      check(_TestFieldPromotability().run([c, d, e])).unorderedEquals({'_f'});
+      var nonPromotabilityInfo = _TestFieldPromotability().run([c, d, e]);
+      check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+      check(nonPromotabilityInfo['_f']!.interferingNsmClasses)
+          .unorderedEquals([e]);
     });
 
     test('induced by field', () {
@@ -86,7 +141,10 @@
       var c = Class(fields: [f]);
       var d = Class(isAbstract: true, fields: [Field('_f', isFinal: true)]);
       var e = Class(implements: [d]);
-      check(_TestFieldPromotability().run([c, d, e])).unorderedEquals({'_f'});
+      var nonPromotabilityInfo = _TestFieldPromotability().run([c, d, e]);
+      check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+      check(nonPromotabilityInfo['_f']!.interferingNsmClasses)
+          .unorderedEquals([e]);
     });
   });
 
@@ -95,8 +153,9 @@
     var c = Class(fields: [f]);
     var d = Class(isAbstract: true, getters: [Getter('_f', isAbstract: true)]);
     var e = Class(isAbstract: true, implements: [d]);
-    check(_TestFieldPromotability().run([c, d, e])).unorderedEquals({});
-    check(f.isPossiblyPromotable).isTrue();
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c, d, e]);
+    check(nonPromotabilityInfo).isEmpty();
+    check(f.nonPromotabilityReason).equals(null);
   });
 
   test('unimplemented abstract field renders a field non-promotable:', () {
@@ -106,7 +165,10 @@
         isAbstract: true,
         fields: [Field('_f', isAbstract: true, isFinal: true)]);
     var e = Class(extendsOrMixesIn: [d]);
-    check(_TestFieldPromotability().run([c, d, e])).unorderedEquals({'_f'});
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c, d, e]);
+    check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+    check(nonPromotabilityInfo['_f']!.interferingNsmClasses)
+        .unorderedEquals([e]);
   });
 
   test('implementations are inherited transitively', () {
@@ -116,8 +178,9 @@
     var c = Class(fields: [f]);
     var d = Class(extendsOrMixesIn: [c]);
     var e = Class(extendsOrMixesIn: [d], implements: [c]);
-    check(_TestFieldPromotability().run([c, d, e])).unorderedEquals({});
-    check(f.isPossiblyPromotable).isTrue();
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c, d, e]);
+    check(nonPromotabilityInfo).isEmpty();
+    check(f.nonPromotabilityReason).equals(null);
   });
 
   test('interfaces are inherited transitively', () {
@@ -127,7 +190,10 @@
     var c = Class(fields: [f]);
     var d = Class(isAbstract: true, implements: [c]);
     var e = Class(implements: [d]);
-    check(_TestFieldPromotability().run([c, d, e])).unorderedEquals({'_f'});
+    var nonPromotabilityInfo = _TestFieldPromotability().run([c, d, e]);
+    check(nonPromotabilityInfo.keys).unorderedEquals({'_f'});
+    check(nonPromotabilityInfo['_f']!.interferingNsmClasses)
+        .unorderedEquals([e]);
   });
 
   test('class hierarchy circularities are handled', () {
@@ -162,7 +228,7 @@
   final bool isFinal;
   final bool isAbstract;
   final bool isExternal;
-  late final bool isPossiblyPromotable;
+  late final PropertyNonPromotabilityReason? nonPromotabilityReason;
 
   Field(this.name,
       {this.isFinal = false, this.isAbstract = false, this.isExternal = false});
@@ -175,7 +241,7 @@
   Getter(this.name, {this.isAbstract = false});
 }
 
-class _TestFieldPromotability extends FieldPromotability<Class> {
+class _TestFieldPromotability extends FieldPromotability<Class, Field, Getter> {
   @override
   Iterable<Class> getSuperclasses(Class class_,
       {required bool ignoreImplements}) {
@@ -186,23 +252,25 @@
     }
   }
 
-  Set<String> run(Iterable<Class> classes) {
+  Map<String, FieldNameNonPromotabilityInfo<Class, Field, Getter>> run(
+      Iterable<Class> classes) {
     // Iterate through all the classes, enums, and mixins in the library,
     // recording the non-synthetic instance fields and getters of each.
     for (var class_ in classes) {
       var classInfo = addClass(class_, isAbstract: class_.isAbstract);
       for (var field in class_.fields) {
-        field.isPossiblyPromotable = addField(classInfo, field.name,
+        field.nonPromotabilityReason = addField(classInfo, field, field.name,
             isFinal: field.isFinal,
             isAbstract: field.isAbstract,
             isExternal: field.isExternal);
       }
       for (var getter in class_.getters) {
-        addGetter(classInfo, getter.name, isAbstract: getter.isAbstract);
+        addGetter(classInfo, getter, getter.name,
+            isAbstract: getter.isAbstract);
       }
     }
 
-    // Compute the set of field names that are not promotable.
-    return computeUnpromotablePrivateFieldNames();
+    // Compute field non-promotability info.
+    return computeNonPromotabilityInfo();
   }
 }
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 3e52c6e..f6f88d7 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -5,6 +5,7 @@
 import 'dart:core' as core;
 import 'dart:core';
 
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_link.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
@@ -5761,7 +5762,8 @@
     group('because property', () {
       test('via explicit this', () {
         h.thisType = 'C';
-        h.addMember('C', 'field', 'Object?');
+        h.addMember('C', 'field', 'Object?',
+            whyNotPromotable: PropertyNonPromotabilityReason.isNotEnabled);
         h.run([
           if_(this_.property('field').eq(nullLiteral), [
             return_(),
@@ -5770,15 +5772,18 @@
             expect(reasons.keys, unorderedEquals([Type('Object')]));
             var nonPromotionReason =
                 reasons.values.single as PropertyNotPromoted;
+            expect(nonPromotionReason.whyNotPromotable,
+                PropertyNonPromotabilityReason.isNotEnabled);
             expect(nonPromotionReason.documentationLink,
-                NonPromotionDocumentationLink.property);
+                NonPromotionDocumentationLink.fieldPromotionUnavailable);
           }),
         ]);
       });
 
       test('via implicit this/super', () {
         h.thisType = 'C';
-        h.addMember('C', 'field', 'Object?');
+        h.addMember('C', 'field', 'Object?',
+            whyNotPromotable: PropertyNonPromotabilityReason.isNotEnabled);
         h.run([
           if_(thisProperty('field').eq(nullLiteral), [
             return_(),
@@ -5787,14 +5792,17 @@
             expect(reasons.keys, unorderedEquals([Type('Object')]));
             var nonPromotionReason =
                 reasons.values.single as PropertyNotPromoted;
+            expect(nonPromotionReason.whyNotPromotable,
+                PropertyNonPromotabilityReason.isNotEnabled);
             expect(nonPromotionReason.documentationLink,
-                NonPromotionDocumentationLink.property);
+                NonPromotionDocumentationLink.fieldPromotionUnavailable);
           }),
         ]);
       });
 
       test('via variable', () {
-        h.addMember('C', 'field', 'Object?');
+        h.addMember('C', 'field', 'Object?',
+            whyNotPromotable: PropertyNonPromotabilityReason.isNotEnabled);
         var x = Var('x');
         h.run([
           declare(x, type: 'C', initializer: expr('C')),
@@ -5805,8 +5813,10 @@
             expect(reasons.keys, unorderedEquals([Type('Object')]));
             var nonPromotionReason =
                 reasons.values.single as PropertyNotPromoted;
+            expect(nonPromotionReason.whyNotPromotable,
+                PropertyNonPromotabilityReason.isNotEnabled);
             expect(nonPromotionReason.documentationLink,
-                NonPromotionDocumentationLink.property);
+                NonPromotionDocumentationLink.fieldPromotionUnavailable);
           }),
         ]);
       });
diff --git a/pkg/_fe_analyzer_shared/test/mini_ast.dart b/pkg/_fe_analyzer_shared/test/mini_ast.dart
index b6073d8..5ef0cc0 100644
--- a/pkg/_fe_analyzer_shared/test/mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/mini_ast.dart
@@ -6,6 +6,9 @@
 /// flow analysis.  Callers may use the top level methods in this file to create
 /// AST nodes and then feed them to [Harness.run] to run them through flow
 /// analysis testing.
+library;
+
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart'
     show
         CascadePropertyTarget,
@@ -17,16 +20,16 @@
         SuperPropertyTarget,
         ThisPropertyTarget;
 import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
-import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart'
     as shared;
+import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
+import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer.dart'
+    as shared;
 import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer.dart'
     hide MapPatternEntry, NamedType, RecordPatternField, RecordType;
-import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer.dart'
-    as shared;
-import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart'
     as shared;
+import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/variable_bindings.dart';
 import 'package:test/test.dart';
 
@@ -1634,7 +1637,8 @@
 
   late final Map<String, _PropertyElement?> _members = {
     for (var entry in _coreMemberTypes.entries)
-      entry.key: _PropertyElement(entry.value)
+      entry.key: _PropertyElement(entry.value,
+          isPromotable: false, whyNotPromotable: null)
   };
 
   late final typeAnalyzer = _MiniAstTypeAnalyzer(
@@ -1700,7 +1704,11 @@
   /// [targetType] should result in `null` (no such member) rather than a test
   /// failure.
   void addMember(String targetType, String memberName, String? type,
-      {bool promotable = false}) {
+      {bool promotable = false,
+      PropertyNonPromotabilityReason? whyNotPromotable}) {
+    if (promotable) {
+      assert(whyNotPromotable == null);
+    }
     var query = '$targetType.$memberName';
     if (type == null) {
       if (promotable) {
@@ -1710,11 +1718,8 @@
       _members[query] = null;
       return;
     }
-    var member = _PropertyElement(Type(type));
-    _members[query] = member;
-    if (promotable) {
-      _operations.promotableFields.add(member);
-    }
+    _members[query] = _PropertyElement(Type(type),
+        isPromotable: promotable, whyNotPromotable: whyNotPromotable);
   }
 
   void addPromotionException(String from, String to, String result) {
@@ -2667,8 +2672,6 @@
   Map<String, bool> _areStructurallyEqualResults =
       Map.of(_coreAreStructurallyEqualResults);
 
-  final Set<_PropertyElement> promotableFields = {};
-
   final TypeSystem _typeSystem = TypeSystem();
 
   @override
@@ -2782,8 +2785,8 @@
   }
 
   @override
-  bool isPropertyPromotable(Object property) =>
-      promotableFields.contains(property);
+  bool isPropertyPromotable(covariant _PropertyElement property) =>
+      property.isPromotable;
 
   @override
   bool isSameType(Type type1, Type type2) {
@@ -2884,6 +2887,11 @@
     return variable.type;
   }
 
+  @override
+  PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(
+          covariant _PropertyElement property) =>
+      property.whyNotPromotable;
+
   Type _lub(Type type1, Type type2) {
     if (isSameType(type1, type2)) {
       return type1;
@@ -5864,7 +5872,26 @@
   /// The type of the property.
   final Type _type;
 
-  _PropertyElement(this._type);
+  /// Whether the property is promotable.
+  final bool isPromotable;
+
+  /// The reason the property is not promotable, if applicable and relevant to
+  /// the test.
+  ///
+  /// If the propery is promotable ([isPromotable] is `true`), this value is
+  /// always `null`.
+  ///
+  /// Otherwise the value *may* be a reason for the property not being
+  /// promotable, but it may also still be `null` if the reason is not relevant
+  /// to the test.
+  final PropertyNonPromotabilityReason? whyNotPromotable;
+
+  _PropertyElement(this._type,
+      {required this.isPromotable, required this.whyNotPromotable}) {
+    if (isPromotable) {
+      assert(whyNotPromotable == null);
+    }
+  }
 }
 
 class _VariableBinder extends VariableBinder<Node, Var> {
diff --git a/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart b/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart
index 7ed6293..90dfddd 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/static_interop_class_eraser.dart
@@ -155,7 +155,8 @@
     'ui',
     'ui_web',
     '_engine',
-    '_skwasm_impl'
+    '_skwasm_impl',
+    '_wasm',
   };
 
   StaticInteropClassEraser(CoreTypes coreTypes, this.referenceFromIndex,
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index 65d7831..ca568b5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
@@ -523,6 +524,31 @@
   DartType variableType(PromotableElement variable) {
     return variable.type;
   }
+
+  @override
+  PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(
+      covariant ExecutableElement property) {
+    if (!property.library.featureSet.isEnabled(Feature.inference_update_2)) {
+      return PropertyNonPromotabilityReason.isNotEnabled;
+    }
+    if (property is! PropertyAccessorElement) {
+      return PropertyNonPromotabilityReason.isNotField;
+    }
+    var field = property.variable;
+    if (field is! FieldElement) {
+      return PropertyNonPromotabilityReason.isNotField;
+    }
+    if (field.isSynthetic && !property.isSynthetic) {
+      // The field is synthetic but not the property; this means that what was
+      // declared by the user was the property (the getter).
+      return PropertyNonPromotabilityReason.isNotField;
+    }
+    if (field.isPromotable) return null;
+    if (field.isPublic) return PropertyNonPromotabilityReason.isNotPrivate;
+    if (field.isExternal) return PropertyNonPromotabilityReason.isExternal;
+    if (!field.isFinal) return PropertyNonPromotabilityReason.isNotFinal;
+    return PropertyNonPromotabilityReason.isInterferedWith;
+  }
 }
 
 /// The visitor that gathers local variables that are potentially assigned
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index f6054d1..9dc80fa 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4,6 +4,7 @@
 
 import 'dart:collection';
 
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart'
     as shared;
@@ -5351,10 +5352,44 @@
       PropertyNotPromoted<DartType> reason) {
     var receiverElement = reason.propertyMember;
     if (receiverElement is PropertyAccessorElement) {
-      propertyReference = receiverElement;
+      var property = propertyReference = receiverElement;
       propertyType = reason.staticType;
-      return _contextMessageForProperty(
-          receiverElement, reason.propertyName, reason);
+      var propertyName = reason.propertyName;
+      String message;
+      switch (reason.whyNotPromotable) {
+        case PropertyNonPromotabilityReason.isNotEnabled:
+          message =
+              "'$propertyName' refers to a field. It couldn't be promoted "
+              "because field promotion is only available in Dart 3.2 and "
+              "above.";
+        case PropertyNonPromotabilityReason.isNotField:
+          message =
+              "'$propertyName' refers to a getter so it couldn't be promoted.";
+        case PropertyNonPromotabilityReason.isNotPrivate:
+          message =
+              "'$propertyName' refers to a public field so it couldn't be "
+              "promoted.";
+        case PropertyNonPromotabilityReason.isExternal:
+          message =
+              "'$propertyName' refers to an external field so it couldn't be "
+              "promoted.";
+        case PropertyNonPromotabilityReason.isNotFinal:
+          message =
+              "'$propertyName' refers to a non-final field so it couldn't be "
+              "promoted.";
+        case PropertyNonPromotabilityReason.isInterferedWith:
+          // TODO(paulberry): Generate a context message for each conflicting
+          // declaration.
+          return null;
+      }
+      return DiagnosticMessageImpl(
+          filePath: property.source.fullName,
+          message: message,
+          offset: property.nonSynthetic.nameOffset,
+          length: property.nameLength,
+          // TODO(paulberry): Handle the case where there is no documentation
+          // link.
+          url: reason.documentationLink?.url);
     } else {
       assert(receiverElement == null,
           'Unrecognized property element: ${receiverElement.runtimeType}');
@@ -5372,21 +5407,8 @@
         url: reason.documentationLink.url);
   }
 
-  DiagnosticMessageImpl _contextMessageForProperty(
-      PropertyAccessorElement property,
-      String propertyName,
-      NonPromotionReason reason) {
-    return DiagnosticMessageImpl(
-        filePath: property.source.fullName,
-        message:
-            "'$propertyName' refers to a property so it couldn't be promoted",
-        offset: property.nonSynthetic.nameOffset,
-        length: property.nameLength,
-        url: reason.documentationLink.url);
-  }
-
-  DiagnosticMessageImpl _contextMessageForWrite(
-      String variableName, AstNode node, NonPromotionReason reason) {
+  DiagnosticMessageImpl _contextMessageForWrite(String variableName,
+      AstNode node, DemoteViaExplicitWrite<PromotableElement> reason) {
     return DiagnosticMessageImpl(
         filePath: source.fullName,
         message: "Variable '$variableName' could not be promoted due to an "
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 4112774..4084f48 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -1188,7 +1188,8 @@
 
 /// This class examines all the [InterfaceElement]s in a library and determines
 /// which fields are promotable within that library.
-class _FieldPromotability extends FieldPromotability<InterfaceElement> {
+class _FieldPromotability extends FieldPromotability<InterfaceElement,
+    FieldElement, PropertyAccessorElement> {
   /// The [_libraryBuilder] for the library being analyzed.
   final LibraryBuilder _libraryBuilder;
 
@@ -1239,11 +1240,11 @@
     }
 
     // Compute the set of field names that are not promotable.
-    var unpromotableFieldNames = computeUnpromotablePrivateFieldNames();
+    var fieldNonPromotabilityInfo = computeNonPromotabilityInfo();
 
     // Set the `isPromotable` bit for each field element that *is* promotable.
     for (var field in _potentiallyPromotableFields) {
-      if (!unpromotableFieldNames.contains(field.name)) {
+      if (fieldNonPromotabilityInfo[field.name] == null) {
         field.isPromotable = true;
       }
     }
@@ -1258,11 +1259,11 @@
         continue;
       }
 
-      var isPotentiallyPromotable = addField(classInfo, field.name,
+      var nonPromotabilityReason = addField(classInfo, field, field.name,
           isFinal: field.isFinal,
           isAbstract: field.isAbstract,
           isExternal: field.isExternal);
-      if (isPotentiallyPromotable) {
+      if (nonPromotabilityReason == null) {
         _potentiallyPromotableFields.add(field);
       }
     }
@@ -1272,7 +1273,8 @@
         continue;
       }
 
-      addGetter(classInfo, accessor.name, isAbstract: accessor.isAbstract);
+      addGetter(classInfo, accessor, accessor.name,
+          isAbstract: accessor.isAbstract);
     }
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index fb7452a..86d5291 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -269,10 +269,8 @@
 
   /// If `null`, [SourceLoader.computeFieldPromotability] hasn't been called
   /// yet, or field promotion is disabled for this library.  If not `null`,
-  /// field promotion is enabled for this library and this is the set of private
-  /// field names for which promotion is blocked due to the presence of a
-  /// non-final field or a concrete getter.
-  Set<String>? unpromotablePrivateFieldNames;
+  /// information about which fields are promotable in this library.
+  FieldNonPromotabilityInfo? fieldNonPromotabilityInfo;
 
   SourceLibraryBuilder.internal(
       SourceLoader loader,
@@ -1618,16 +1616,16 @@
     return count;
   }
 
-  /// Sets [unpromotablePrivateFieldNames] based on the contents of this
-  /// library.
+  /// Sets [fieldNonPromotabilityInfo] based on the contents of this library.
   void computeFieldPromotability() {
     _FieldPromotability fieldPromotability = new _FieldPromotability();
+    Map<Member, PropertyNonPromotabilityReason> individualPropertyReasons = {};
 
     // Iterate through all the classes, enums, and mixins in the library,
     // recording the non-synthetic instance fields and getters of each.
-    Iterator<SourceClassBuilder> iterator = localMembersIteratorOfType();
-    while (iterator.moveNext()) {
-      SourceClassBuilder class_ = iterator.current;
+    Iterator<SourceClassBuilder> classIterator = localMembersIteratorOfType();
+    while (classIterator.moveNext()) {
+      SourceClassBuilder class_ = classIterator.current;
       ClassInfo<Class> classInfo = fieldPromotability.addClass(class_.actualCls,
           isAbstract: class_.isAbstract);
       Iterator<SourceMemberBuilder> memberIterator =
@@ -1637,23 +1635,43 @@
         if (member.isStatic) continue;
         if (member is SourceFieldBuilder) {
           if (member.isSynthesized) continue;
-          // Note: external fields have already been de-sugared into getters, so
-          // we can just pass `false` for `isExternal`.
-          fieldPromotability.addField(classInfo, member.name,
+          PropertyNonPromotabilityReason? reason = fieldPromotability.addField(
+              classInfo, member, member.name,
               isFinal: member.isFinal,
               isAbstract: member.isAbstract,
-              isExternal: false);
+              isExternal: member.isExternal);
+          if (reason != null) {
+            individualPropertyReasons[member.readTarget] = reason;
+          }
         } else if (member is SourceProcedureBuilder && member.isGetter) {
           if (member.isSynthetic) continue;
-          fieldPromotability.addGetter(classInfo, member.name,
+          fieldPromotability.addGetter(classInfo, member, member.name,
               isAbstract: member.isAbstract);
+          individualPropertyReasons[member.procedure] =
+              PropertyNonPromotabilityReason.isNotField;
         }
       }
     }
 
-    // Compute the set of field names that are not promotable.
-    unpromotablePrivateFieldNames =
-        fieldPromotability.computeUnpromotablePrivateFieldNames();
+    // And for each extension getter, make a note of why it's not promotable.
+    Iterator<SourceExtensionBuilder> extensionIterator =
+        localMembersIteratorOfType();
+    while (extensionIterator.moveNext()) {
+      SourceExtensionBuilder extension_ = extensionIterator.current;
+      for (Builder member in extension_.scope.localMembers) {
+        if (member is SourceProcedureBuilder &&
+            !member.isStatic &&
+            member.isGetter) {
+          individualPropertyReasons[member.procedure] =
+              PropertyNonPromotabilityReason.isNotField;
+        }
+      }
+    }
+
+    // Compute information about field non-promotability.
+    fieldNonPromotabilityInfo = new FieldNonPromotabilityInfo(
+        fieldNameInfo: fieldPromotability.computeNonPromotabilityInfo(),
+        individualPropertyReasons: individualPropertyReasons);
   }
 
   @override
@@ -5480,7 +5498,8 @@
 
 /// This class examines all the [Class]es in a library and determines which
 /// fields are promotable within that library.
-class _FieldPromotability extends FieldPromotability<Class> {
+class _FieldPromotability extends FieldPromotability<Class, SourceFieldBuilder,
+    SourceProcedureBuilder> {
   @override
   Iterable<Class> getSuperclasses(Class class_,
       {required bool ignoreImplements}) {
@@ -5983,6 +6002,30 @@
       this.charEndOffset);
 }
 
+/// Information about which fields are promotable in a given library.
+class FieldNonPromotabilityInfo {
+  /// Map whose keys are private field names for which promotion is blocked, and
+  /// whose values are [FieldNameNonPromotabilityInfo] objects containing
+  /// information about why promotion is blocked for the given name.
+  ///
+  /// This map is the final arbiter on whether a given property access is
+  /// considered promotable, but since it is keyed on the field name, it doesn't
+  /// always provide the most specific information about *why* a given property
+  /// isn't promotable; for more detailed information about a specific property,
+  /// see [individualPropertyReasons].
+  final Map<
+      String,
+      FieldNameNonPromotabilityInfo<Class, SourceFieldBuilder,
+          SourceProcedureBuilder>> fieldNameInfo;
+
+  /// Map whose keys are the members that a property get might resolve to, and
+  /// whose values are the reasons why the given property couldn't be promoted.
+  final Map<Member, PropertyNonPromotabilityReason> individualPropertyReasons;
+
+  FieldNonPromotabilityInfo(
+      {required this.fieldNameInfo, required this.individualPropertyReasons});
+}
+
 Uri computeLibraryUri(Builder declaration) {
   Builder? current = declaration;
   while (current != null) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
index 83efa3b..6c43401d 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:_fe_analyzer_shared/src/deferred_function_literal_heuristic.dart';
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
 import 'package:_fe_analyzer_shared/src/testing/id.dart';
@@ -4455,8 +4456,27 @@
     if (member is Member) {
       propertyReference = member;
       propertyType = reason.staticType;
-      return templateFieldNotPromoted
-          .withArguments(reason.propertyName, reason.documentationLink.url)
+      Template<Message Function(String, String)> template;
+      switch (reason.whyNotPromotable) {
+        case PropertyNonPromotabilityReason.isNotEnabled:
+          template = templateFieldNotPromotedBecauseNotEnabled;
+        case PropertyNonPromotabilityReason.isNotField:
+          template = templateFieldNotPromotedBecauseNotField;
+        case PropertyNonPromotabilityReason.isNotPrivate:
+          template = templateFieldNotPromotedBecauseNotPrivate;
+        case PropertyNonPromotabilityReason.isExternal:
+          template = templateFieldNotPromotedBecauseExternal;
+        case PropertyNonPromotabilityReason.isNotFinal:
+          template = templateFieldNotPromotedBecauseNotFinal;
+        case PropertyNonPromotabilityReason.isInterferedWith:
+          // TODO(paulberry): Generate a context message for each conflicting
+          // declaration.
+          return null;
+      }
+      // TODO(paulberry): Handle the case where there is no documentation link.
+      return template
+          .withArguments(
+              reason.propertyName, reason.documentationLink?.url ?? '')
           .withLocation(member.fileUri, member.fileOffset, noLength);
     } else {
       assert(member == null,
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 761b37c..dda8a48 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
@@ -20,7 +21,8 @@
 import '../kernel/internal_ast.dart';
 import '../kernel/kernel_helper.dart';
 import '../source/source_constructor_builder.dart';
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_library_builder.dart'
+    show FieldNonPromotabilityInfo, SourceLibraryBuilder;
 import 'factor_type.dart';
 import 'type_inferrer.dart';
 import 'type_schema_environment.dart' show TypeSchemaEnvironment;
@@ -464,10 +466,8 @@
   final Nullability nullability;
 
   /// If `null`, field promotion is disabled for this library.  If not `null`,
-  /// field promotion is enabled for this library and this is the set of private
-  /// field names for which promotion is blocked due to the presence of a
-  /// non-final field or a concrete getter.
-  final Set<String>? unpromotablePrivateFieldNames;
+  /// information about which fields are promotable in this library.
+  final FieldNonPromotabilityInfo? fieldNonPromotabilityInfo;
 
   final Map<DartType, DartType> typeCacheNonNullable;
   final Map<DartType, DartType> typeCacheNullable;
@@ -475,7 +475,7 @@
 
   OperationsCfe(this.typeEnvironment,
       {required this.nullability,
-      this.unpromotablePrivateFieldNames,
+      this.fieldNonPromotabilityInfo,
       required this.typeCacheNonNullable,
       required this.typeCacheNullable,
       required this.typeCacheLegacy});
@@ -510,9 +510,9 @@
 
   @override
   bool isPropertyPromotable(covariant Member property) {
-    Set<String>? unpromotablePrivateFieldNames =
-        this.unpromotablePrivateFieldNames;
-    if (unpromotablePrivateFieldNames == null) return false;
+    FieldNonPromotabilityInfo? fieldNonPromotabilityInfo =
+        this.fieldNonPromotabilityInfo;
+    if (fieldNonPromotabilityInfo == null) return false;
     if (property is Procedure) {
       if (property.isAbstractFieldAccessor || property.isLoweredLateField) {
         // Property was declared as a field; it was lowered to a getter or
@@ -525,7 +525,18 @@
     }
     String name = property.name.text;
     if (!name.startsWith('_')) return false;
-    return !unpromotablePrivateFieldNames.contains(name);
+    return fieldNonPromotabilityInfo.fieldNameInfo[name] == null;
+  }
+
+  @override
+  PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(
+      covariant Member property) {
+    FieldNonPromotabilityInfo? fieldNonPromotabilityInfo =
+        this.fieldNonPromotabilityInfo;
+    if (fieldNonPromotabilityInfo == null) {
+      return PropertyNonPromotabilityReason.isNotEnabled;
+    }
+    return fieldNonPromotabilityInfo.individualPropertyReasons[property];
   }
 
   // TODO(cstefantsova): Consider checking for mutual subtypes instead of ==.
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 dfbbb75..f1f3a56 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
@@ -149,8 +149,7 @@
         typeSchemaEnvironment = engine.typeSchemaEnvironment,
         operations = new OperationsCfe(engine.typeSchemaEnvironment,
             nullability: libraryBuilder.nonNullable,
-            unpromotablePrivateFieldNames:
-                libraryBuilder.unpromotablePrivateFieldNames,
+            fieldNonPromotabilityInfo: libraryBuilder.fieldNonPromotabilityInfo,
             typeCacheNonNullable: engine.typeCacheNonNullable,
             typeCacheNullable: engine.typeCacheNullable,
             typeCacheLegacy: engine.typeCacheLegacy);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index ca763d7..7251b92 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -423,6 +423,21 @@
 FieldNonNullableWithoutInitializerWarning/example: Fail
 FieldNotPromoted/analyzerCode: Fail
 FieldNotPromoted/example: Fail
+FieldNotPromotedBecauseExternal/analyzerCode: Fail
+FieldNotPromotedBecauseExternal/part_wrapped_script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseExternal/script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotEnabled/analyzerCode: Fail
+FieldNotPromotedBecauseNotEnabled/part_wrapped_script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotEnabled/script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotField/analyzerCode: Fail
+FieldNotPromotedBecauseNotField/part_wrapped_script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotField/script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotFinal/analyzerCode: Fail
+FieldNotPromotedBecauseNotFinal/part_wrapped_script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotFinal/script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotPrivate/analyzerCode: Fail
+FieldNotPromotedBecauseNotPrivate/part_wrapped_script: Fail # https://github.com/dart-lang/sdk/issues/53634
+FieldNotPromotedBecauseNotPrivate/script: Fail # https://github.com/dart-lang/sdk/issues/53634
 FinalAndCovariant/part_wrapped_script2: Fail
 FinalAndCovariant/script2: Fail
 FinalClassExtendedOutsideOfLibrary/part_wrapped_script: Fail # Uses imports
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index a9dba5f..0b5be70 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -5468,9 +5468,74 @@
   problemMessage: "Variable '#name' could not be promoted due to an assignment."
   correctionMessage: "Try null checking the variable after the assignment.  See #string"
 
-FieldNotPromoted:
-  problemMessage: "'#name' refers to a property so it couldn't be promoted."
+FieldNotPromotedBecauseNotEnabled:
+  problemMessage: "'#name' refers to a field. It couldn't be promoted because field promotion is only available in Dart 3.2 and above."
   correctionMessage: "See #string"
+  script: >
+    // @dart=3.1
+    class C {
+      final int? _i;
+      C(this._i);
+    }
+    test(C c) {
+      if (c._i != null) {
+        c._i.isEven;
+      }
+    }
+
+FieldNotPromotedBecauseNotField:
+  problemMessage: "'#name' refers to a getter so it couldn't be promoted."
+  correctionMessage: "See #string"
+  script: >
+    class C {
+      int? get _i => 0;
+    }
+    test(C c) {
+      if (c._i != null) {
+        c._i.isEven;
+      }
+    }
+
+FieldNotPromotedBecauseNotPrivate:
+  problemMessage: "'#name' refers to a public field so it couldn't be promoted."
+  correctionMessage: "See #string"
+  script: >
+    class C {
+      final int? i;
+      C(this.i);
+    }
+    test(C c) {
+      if (c.i != null) {
+        c.i.isEven;
+      }
+    }
+
+FieldNotPromotedBecauseExternal:
+  problemMessage: "'#name' refers to an external field so it couldn't be promoted."
+  correctionMessage: "See #string"
+  script: >
+    class C {
+      external final int? _i;
+    }
+    test(C c) {
+      if (c._i != null) {
+        c._i.isEven;
+      }
+    }
+
+FieldNotPromotedBecauseNotFinal:
+  problemMessage: "'#name' refers to a non-final field so it couldn't be promoted."
+  correctionMessage: "See #string"
+  script: >
+    class C {
+      int? _i;
+      C(this._i);
+    }
+    test(C c) {
+      if (c._i != null) {
+        c._i.isEven;
+      }
+    }
 
 ThisNotPromoted:
   problemMessage: "'this' can't be promoted."
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index a2c6929..3dfb6ec 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -19,6 +19,7 @@
 accounting
 accounts
 accumulated
+accumulates
 accumulating
 accumulation
 accumulator
@@ -66,6 +67,7 @@
 apparently
 applicable
 approximation
+arbiter
 architectures
 area
 arg
@@ -442,6 +444,7 @@
 dispose
 disposed
 disposes
+distinguished
 distribute
 diverged
 divided
@@ -790,6 +793,8 @@
 interacts
 interested
 interfere
+interfered
+interfering
 interim
 interior
 interleaved
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index a84098c..61a165c 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 110;
+  UInt32 formatVersion = 111;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -1000,6 +1000,7 @@
 
 type StringLiteral extends Expression {
   Byte tag = 39;
+  FileOffset fileOffset;
   StringReference value;
 }
 
@@ -1008,42 +1009,51 @@
 type SpecializedIntLiteral extends IntegerLiteral {
   Byte tag = 240 + N; // Where 0 <= N < 8.
   // Integer literal with value (N - 3), that is, an integer in range -3..4.
+  FileOffset fileOffset;
 }
 
 type PositiveIntLiteral extends IntegerLiteral {
   Byte tag = 55;
+  FileOffset fileOffset;
   UInt value;
 }
 
 type NegativeIntLiteral extends IntegerLiteral {
   Byte tag = 56;
+  FileOffset fileOffset;
   UInt absoluteValue;
 }
 
 type BigIntLiteral extends IntegerLiteral {
   Byte tag = 57;
+  FileOffset fileOffset;
   StringReference valueString;
 }
 
 type DoubleLiteral extends Expression {
   Byte tag = 40;
+  FileOffset fileOffset;
   Double value;
 }
 
 type TrueLiteral extends Expression {
   Byte tag = 41;
+  FileOffset fileOffset;
 }
 
 type FalseLiteral extends Expression {
   Byte tag = 42;
+  FileOffset fileOffset;
 }
 
 type NullLiteral extends Expression {
   Byte tag = 43;
+  FileOffset fileOffset;
 }
 
 type SymbolLiteral extends Expression {
   Byte tag = 44;
+  FileOffset fileOffset;
   StringReference value; // Everything strictly after the '#'.
 }
 
@@ -1055,6 +1065,7 @@
 
 type ThisExpression extends Expression {
   Byte tag = 46;
+  FileOffset fileOffset;
 }
 
 type Rethrow extends Expression {
@@ -1438,6 +1449,7 @@
 
 type TryCatch extends Statement {
   Byte tag = 75;
+  FileOffset fileOffset;
   Statement body;
   // "any catch needs a stacktrace" means it has a stacktrace variable.
   Byte flags (anyCatchNeedsStackTrace, isSynthesized);
@@ -1454,6 +1466,7 @@
 
 type TryFinally extends Statement {
   Byte tag = 76;
+  FileOffset fileOffset;
   Statement body;
   Statement finalizer;
 }
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 070275f..69115c0 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2736,44 +2736,56 @@
   }
 
   Expression _readStringLiteral() {
-    return new StringLiteral(readStringReference());
+    int offset = readOffset();
+    return new StringLiteral(readStringReference())..fileOffset = offset;
   }
 
   Expression _readSpecializedIntLiteral(int tagByte) {
     int biasedValue = tagByte & Tag.SpecializedPayloadMask;
-    return new IntLiteral(biasedValue - Tag.SpecializedIntLiteralBias);
+    return new IntLiteral(biasedValue - Tag.SpecializedIntLiteralBias)
+      ..fileOffset = readOffset();
   }
 
   Expression _readPositiveIntLiteral() {
-    return new IntLiteral(readUInt30());
+    int offset = readOffset();
+    int value = readUInt30();
+    return new IntLiteral(value)..fileOffset = offset;
   }
 
   Expression _readNegativeIntLiteral() {
-    return new IntLiteral(-readUInt30());
+    int offset = readOffset();
+    int value = -readUInt30();
+    return new IntLiteral(value)..fileOffset = offset;
   }
 
   Expression _readBigIntLiteral() {
-    return new IntLiteral(int.parse(readStringReference()));
+    int offset = readOffset();
+    int value = int.parse(readStringReference());
+    return new IntLiteral(value)..fileOffset = offset;
   }
 
   Expression _readDoubleLiteral() {
-    return new DoubleLiteral(readDouble());
+    int offset = readOffset();
+    double value = readDouble();
+    return new DoubleLiteral(value)..fileOffset = offset;
   }
 
   Expression _readTrueLiteral() {
-    return new BoolLiteral(true);
+    return new BoolLiteral(true)..fileOffset = readOffset();
   }
 
   Expression _readFalseLiteral() {
-    return new BoolLiteral(false);
+    return new BoolLiteral(false)..fileOffset = readOffset();
   }
 
   Expression _readNullLiteral() {
-    return new NullLiteral();
+    return new NullLiteral()..fileOffset = readOffset();
   }
 
   Expression _readSymbolLiteral() {
-    return new SymbolLiteral(readStringReference());
+    int offset = readOffset();
+    String value = readStringReference();
+    return new SymbolLiteral(value)..fileOffset = offset;
   }
 
   Expression _readTypeLiteral() {
@@ -2782,7 +2794,7 @@
   }
 
   Expression _readThisLiteral() {
-    return new ThisExpression();
+    return new ThisExpression()..fileOffset = readOffset();
   }
 
   Expression _readRethrow() {
@@ -3615,13 +3627,17 @@
   }
 
   Statement _readTryCatch() {
+    int offset = readOffset();
     Statement body = readStatement();
     int flags = readByte();
-    return new TryCatch(body, readCatchList(), isSynthetic: flags & 2 == 2);
+    return new TryCatch(body, readCatchList(), isSynthetic: flags & 2 == 2)
+      ..fileOffset = offset;
   }
 
   Statement _readTryFinally() {
-    return new TryFinally(readStatement(), readStatement());
+    int offset = readOffset();
+    return new TryFinally(readStatement(), readStatement())
+      ..fileOffset = offset;
   }
 
   Statement _readYieldStatement() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 7c6a402..25dcd91 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -223,7 +223,7 @@
       writeByte(constant.value ? 1 : 0);
     } else if (constant is IntConstant) {
       writeByte(ConstantTag.IntConstant);
-      writeInteger(constant.value);
+      writeInteger(constant.value, TreeNode.noOffset);
     } else if (constant is DoubleConstant) {
       writeByte(ConstantTag.DoubleConstant);
       writeDouble(constant.value);
@@ -1998,30 +1998,35 @@
   @override
   void visitStringLiteral(StringLiteral node) {
     writeByte(Tag.StringLiteral);
+    writeOffset(node.fileOffset);
     writeStringReference(node.value);
   }
 
   @override
   void visitIntLiteral(IntLiteral node) {
-    writeInteger(node.value);
+    writeInteger(node.value, node.fileOffset);
   }
 
-  void writeInteger(int value) {
+  void writeInteger(int value, int fileOffset) {
     int biasedValue = value + Tag.SpecializedIntLiteralBias;
     if (biasedValue >= 0 &&
         biasedValue & Tag.SpecializedPayloadMask == biasedValue) {
       writeByte(Tag.SpecializedIntLiteral + biasedValue);
+      writeOffset(fileOffset);
     } else if (value.abs() >> 30 == 0) {
       if (value < 0) {
         writeByte(Tag.NegativeIntLiteral);
+        writeOffset(fileOffset);
         writeUInt30(-value);
       } else {
         writeByte(Tag.PositiveIntLiteral);
+        writeOffset(fileOffset);
         writeUInt30(value);
       }
     } else {
       // TODO: Pick a better format for big int literals.
       writeByte(Tag.BigIntLiteral);
+      writeOffset(fileOffset);
       writeStringReference('$value');
     }
   }
@@ -2029,6 +2034,7 @@
   @override
   void visitDoubleLiteral(DoubleLiteral node) {
     writeByte(Tag.DoubleLiteral);
+    writeOffset(node.fileOffset);
     writeDouble(node.value);
   }
 
@@ -2039,16 +2045,19 @@
   @override
   void visitBoolLiteral(BoolLiteral node) {
     writeByte(node.value ? Tag.TrueLiteral : Tag.FalseLiteral);
+    writeOffset(node.fileOffset);
   }
 
   @override
   void visitNullLiteral(NullLiteral node) {
     writeByte(Tag.NullLiteral);
+    writeOffset(node.fileOffset);
   }
 
   @override
   void visitSymbolLiteral(SymbolLiteral node) {
     writeByte(Tag.SymbolLiteral);
+    writeOffset(node.fileOffset);
     writeStringReference(node.value);
   }
 
@@ -2062,6 +2071,7 @@
   @override
   void visitThisExpression(ThisExpression node) {
     writeByte(Tag.ThisExpression);
+    writeOffset(node.fileOffset);
   }
 
   @override
@@ -2362,6 +2372,7 @@
   @override
   void visitTryCatch(TryCatch node) {
     writeByte(Tag.TryCatch);
+    writeOffset(node.fileOffset);
     writeNode(node.body);
     bool needsStackTrace = node.catches.any((Catch c) => c.stackTrace != null);
     writeByte(_encodeTryCatchFlags(needsStackTrace, node.isSynthetic));
@@ -2385,6 +2396,7 @@
   @override
   void visitTryFinally(TryFinally node) {
     writeByte(Tag.TryFinally);
+    writeOffset(node.fileOffset);
     writeNode(node.body);
     writeNode(node.finalizer);
   }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 9a142e5..6ecbd94 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -226,7 +226,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 110;
+  static const int BinaryFormatVersion = 111;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/linter/doc/writing-lints.md b/pkg/linter/doc/writing-lints.md
index 8e2f28f..2beaf3e 100644
--- a/pkg/linter/doc/writing-lints.md
+++ b/pkg/linter/doc/writing-lints.md
@@ -117,21 +117,6 @@
 
     $ dart test/all.dart
 
-alternatively, tests can be run using `pub`:
-
-    $ dart test
-    
-Running a single test can be done using the `rule_debug` helper:
-
-    $ dart test/util/rule_debug.dart always_declare_return_types
-    
-would only test `always_declare_return_types`.  (This can be very handy if you
-want to run tests in the VM debugger).
-
-If you simply want to verify a test, you can run it solo in `pub`:
-
-    $ dart test -N always_declare_return_types
-
 ### Utilities
 
 You'll notice when authoring a new rule that failures cause the AST of the test
diff --git a/pkg/linter/test/util/rule_debug.dart b/pkg/linter/test/util/rule_debug.dart
index 29ee59a..c13bcdc 100644
--- a/pkg/linter/test/util/rule_debug.dart
+++ b/pkg/linter/test/util/rule_debug.dart
@@ -15,9 +15,6 @@
 /// Run, for example, like so:
 ///     dart test/util/rule_debug.dart valid_regexps
 ///
-/// To simply *run* a solo test, consider using `dart test -N`:
-///     dart test -N valid_regexps
-///
 void main(List<String> args) {
   var ruleName = args.first;
   var dir = Directory(ruleTestDataDir).absolute;
diff --git a/pkg/linter/test_data/rules/always_declare_return_types.dart b/pkg/linter/test_data/rules/always_declare_return_types.dart
index af474b3..7d3aadb 100644
--- a/pkg/linter/test_data/rules/always_declare_return_types.dart
+++ b/pkg/linter/test_data/rules/always_declare_return_types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N always_declare_return_types`
-
 main() { } //LINT
 
 bar() => new _Foo(); //LINT
diff --git a/pkg/linter/test_data/rules/always_put_control_body_on_new_line.dart b/pkg/linter/test_data/rules/always_put_control_body_on_new_line.dart
index 39ecb22..a7226b2 100644
--- a/pkg/linter/test_data/rules/always_put_control_body_on_new_line.dart
+++ b/pkg/linter/test_data/rules/always_put_control_body_on_new_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N always_put_control_body_on_new_line`
-
 testIfElse() {
   if (false) return; // LINT
 
diff --git a/pkg/linter/test_data/rules/always_put_required_named_parameters_first.dart b/pkg/linter/test_data/rules/always_put_required_named_parameters_first.dart
index 9c169f8..bbd6774 100644
--- a/pkg/linter/test_data/rules/always_put_required_named_parameters_first.dart
+++ b/pkg/linter/test_data/rules/always_put_required_named_parameters_first.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N always_put_required_named_parameters_first`
-
 import 'package:meta/meta.dart';
 
 m1(
diff --git a/pkg/linter/test_data/rules/always_require_non_null_named_parameters.dart b/pkg/linter/test_data/rules/always_require_non_null_named_parameters.dart
index d1073ff..751955f 100644
--- a/pkg/linter/test_data/rules/always_require_non_null_named_parameters.dart
+++ b/pkg/linter/test_data/rules/always_require_non_null_named_parameters.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N always_require_non_null_named_parameters`
-
 // @dart=2.9
 
 import 'package:meta/meta.dart';
diff --git a/pkg/linter/test_data/rules/always_specify_types.dart b/pkg/linter/test_data/rules/always_specify_types.dart
index 8668aaa..3d1d060 100644
--- a/pkg/linter/test_data/rules/always_specify_types.dart
+++ b/pkg/linter/test_data/rules/always_specify_types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N always_specify_types`
-
 // ignore_for_file: unused_local_variable
 
 import 'package:meta/meta.dart';
diff --git a/pkg/linter/test_data/rules/avoid_bool_literals_in_conditional_expressions.dart b/pkg/linter/test_data/rules/avoid_bool_literals_in_conditional_expressions.dart
index f03862f..26a1643 100644
--- a/pkg/linter/test_data/rules/avoid_bool_literals_in_conditional_expressions.dart
+++ b/pkg/linter/test_data/rules/avoid_bool_literals_in_conditional_expressions.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_bool_literals_in_conditional_expressions`
-
 late bool a, b, c;
 
 var d = a ? true : b; // LINT
diff --git a/pkg/linter/test_data/rules/avoid_catches_without_on_clauses.dart b/pkg/linter/test_data/rules/avoid_catches_without_on_clauses.dart
index 373c7da..741ef20 100644
--- a/pkg/linter/test_data/rules/avoid_catches_without_on_clauses.dart
+++ b/pkg/linter/test_data/rules/avoid_catches_without_on_clauses.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_catches_without_on_clauses`
-
 void bad() {
   try {}
   catch (e) { // LINT
diff --git a/pkg/linter/test_data/rules/avoid_classes_with_only_static_members.dart b/pkg/linter/test_data/rules/avoid_classes_with_only_static_members.dart
index 8f5d1ee..f97d64e 100644
--- a/pkg/linter/test_data/rules/avoid_classes_with_only_static_members.dart
+++ b/pkg/linter/test_data/rules/avoid_classes_with_only_static_members.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_classes_with_only_static_members`
-
 class Bad // LINT
 {
   static int a = 0;
diff --git a/pkg/linter/test_data/rules/avoid_double_and_int_checks.dart b/pkg/linter/test_data/rules/avoid_double_and_int_checks.dart
index 135db6d..141814d 100644
--- a/pkg/linter/test_data/rules/avoid_double_and_int_checks.dart
+++ b/pkg/linter/test_data/rules/avoid_double_and_int_checks.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_double_and_int_checks`
-
 lint_for_double_before_int_check_on_parameter(m) {
   if (m is double) {} //
   else if (m is int) {} // LINT
diff --git a/pkg/linter/test_data/rules/avoid_dynamic_calls.dart b/pkg/linter/test_data/rules/avoid_dynamic_calls.dart
index 94b624c..5481277 100644
--- a/pkg/linter/test_data/rules/avoid_dynamic_calls.dart
+++ b/pkg/linter/test_data/rules/avoid_dynamic_calls.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test test/rule_test.dart -N avoid_dynamic_calls`
-
 import 'dart:core';
 import 'dart:core' as core_top_level_prefix_as;
 
diff --git a/pkg/linter/test_data/rules/avoid_empty_else.dart b/pkg/linter/test_data/rules/avoid_empty_else.dart
index 6695157..63c8977 100644
--- a/pkg/linter/test_data/rules/avoid_empty_else.dart
+++ b/pkg/linter/test_data/rules/avoid_empty_else.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_empty_else`
-
 f() {
   int x = 1, y = 0;
   if (x > y)
diff --git a/pkg/linter/test_data/rules/avoid_field_initializers_in_const_classes.dart b/pkg/linter/test_data/rules/avoid_field_initializers_in_const_classes.dart
index c5de0ff..b95da46 100644
--- a/pkg/linter/test_data/rules/avoid_field_initializers_in_const_classes.dart
+++ b/pkg/linter/test_data/rules/avoid_field_initializers_in_const_classes.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_field_initializers_in_const_classes`
-
 class A {
   final a = const []; // LINT
   const A();
diff --git a/pkg/linter/test_data/rules/avoid_implementing_value_types.dart b/pkg/linter/test_data/rules/avoid_implementing_value_types.dart
index f229a62..fe4e1b8 100644
--- a/pkg/linter/test_data/rules/avoid_implementing_value_types.dart
+++ b/pkg/linter/test_data/rules/avoid_implementing_value_types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_implementing_value_types`
-
 class Size { // OK
   final int inBytes;
   const Size(this.inBytes);
diff --git a/pkg/linter/test_data/rules/avoid_init_to_null.dart b/pkg/linter/test_data/rules/avoid_init_to_null.dart
index 1d753cf..ac4ac8b 100644
--- a/pkg/linter/test_data/rules/avoid_init_to_null.dart
+++ b/pkg/linter/test_data/rules/avoid_init_to_null.dart
@@ -4,8 +4,6 @@
 
 // @dart=2.9
 
-// test w/ `dart test -N avoid_init_to_null`
-
 var x = null; //LINT
 var y; //OK
 var z = 1; //OK
diff --git a/pkg/linter/test_data/rules/avoid_js_rounded_ints.dart b/pkg/linter/test_data/rules/avoid_js_rounded_ints.dart
index 32f0522..dd561b3 100644
--- a/pkg/linter/test_data/rules/avoid_js_rounded_ints.dart
+++ b/pkg/linter/test_data/rules/avoid_js_rounded_ints.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_js_rounded_ints`
-
 final i1 = 1; // OK
 final i2 = -45321; // OK
 final i3 = 24361; // OK
diff --git a/pkg/linter/test_data/rules/avoid_multiple_declarations_per_line.dart b/pkg/linter/test_data/rules/avoid_multiple_declarations_per_line.dart
index d35c9a4..3c23858 100644
--- a/pkg/linter/test_data/rules/avoid_multiple_declarations_per_line.dart
+++ b/pkg/linter/test_data/rules/avoid_multiple_declarations_per_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_multiple_declarations_per_line`
-
 // ignore_for_file: unused_local_variable
 
 String? badFoo, badBar, badBaz; // LINT
diff --git a/pkg/linter/test_data/rules/avoid_null_checks_in_equality_operators.dart b/pkg/linter/test_data/rules/avoid_null_checks_in_equality_operators.dart
index 019a3b7..eb3df93 100644
--- a/pkg/linter/test_data/rules/avoid_null_checks_in_equality_operators.dart
+++ b/pkg/linter/test_data/rules/avoid_null_checks_in_equality_operators.dart
@@ -2,9 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_null_checks_in_equality_operators`
-
-
 class P {
   final String name = '';
 
diff --git a/pkg/linter/test_data/rules/avoid_redundant_argument_values.dart b/pkg/linter/test_data/rules/avoid_redundant_argument_values.dart
index 8825e05..c2e5378 100644
--- a/pkg/linter/test_data/rules/avoid_redundant_argument_values.dart
+++ b/pkg/linter/test_data/rules/avoid_redundant_argument_values.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_redundant_argument_values`
-
 import 'package:meta/meta.dart';
 
 class A {
diff --git a/pkg/linter/test_data/rules/avoid_returning_null.dart b/pkg/linter/test_data/rules/avoid_returning_null.dart
index a14783c..18ae354 100644
--- a/pkg/linter/test_data/rules/avoid_returning_null.dart
+++ b/pkg/linter/test_data/rules/avoid_returning_null.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_returning_null`
-
 // @dart=2.9
 
 bool check = true;
diff --git a/pkg/linter/test_data/rules/avoid_returning_null_for_future.dart b/pkg/linter/test_data/rules/avoid_returning_null_for_future.dart
index f106e28..1037368 100644
--- a/pkg/linter/test_data/rules/avoid_returning_null_for_future.dart
+++ b/pkg/linter/test_data/rules/avoid_returning_null_for_future.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_returning_null_for_future`
-
 // @dart=2.8
 
 import 'dart:async';
diff --git a/pkg/linter/test_data/rules/avoid_returning_null_for_void.dart b/pkg/linter/test_data/rules/avoid_returning_null_for_void.dart
index b802f1a..64e5c47 100644
--- a/pkg/linter/test_data/rules/avoid_returning_null_for_void.dart
+++ b/pkg/linter/test_data/rules/avoid_returning_null_for_void.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_returning_null_for_void`
-
 import 'dart:async';
 
 void f1() {
diff --git a/pkg/linter/test_data/rules/avoid_returning_this.dart b/pkg/linter/test_data/rules/avoid_returning_this.dart
index 258d770..d29943d 100644
--- a/pkg/linter/test_data/rules/avoid_returning_this.dart
+++ b/pkg/linter/test_data/rules/avoid_returning_this.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_returning_this`
-
 // ignore_for_file: unused_element
 
 class A {
diff --git a/pkg/linter/test_data/rules/avoid_setters_without_getters.dart b/pkg/linter/test_data/rules/avoid_setters_without_getters.dart
index eb789fa..df28a39 100644
--- a/pkg/linter/test_data/rules/avoid_setters_without_getters.dart
+++ b/pkg/linter/test_data/rules/avoid_setters_without_getters.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_setters_without_getters`
-
 class A {
   set x(int x) {} // LINT
 }
diff --git a/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart b/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart
index 94d809f..46f3cbab 100644
--- a/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart
+++ b/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_shadowing_type_parameters`
 void fn1<T>() {
   void fn2<T>() {} // LINT
   void fn3<U>() {} // OK
diff --git a/pkg/linter/test_data/rules/avoid_type_to_string.dart b/pkg/linter/test_data/rules/avoid_type_to_string.dart
index 79864fb3..9dbc9f2 100644
--- a/pkg/linter/test_data/rules/avoid_type_to_string.dart
+++ b/pkg/linter/test_data/rules/avoid_type_to_string.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_type_to_string`
-
 // SHARED
 
 class A {
diff --git a/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart b/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart
index 3d4ce34..3a89bec 100644
--- a/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart
+++ b/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_types_as_parameter_names`
-
 class SomeType {}
 
 void f() {
diff --git a/pkg/linter/test_data/rules/avoid_unused_constructor_parameters.dart b/pkg/linter/test_data/rules/avoid_unused_constructor_parameters.dart
index 5c573e6..26ab8b0 100644
--- a/pkg/linter/test_data/rules/avoid_unused_constructor_parameters.dart
+++ b/pkg/linter/test_data/rules/avoid_unused_constructor_parameters.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N avoid_unused_constructor_parameters`
-
 class A {
   A(); // OK
 }
diff --git a/pkg/linter/test_data/rules/await_only_futures.dart b/pkg/linter/test_data/rules/await_only_futures.dart
index 727719bb..0eb6211 100644
--- a/pkg/linter/test_data/rules/await_only_futures.dart
+++ b/pkg/linter/test_data/rules/await_only_futures.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N await_only_futures`
-
 import 'dart:async';
 
 bad() async {
diff --git a/pkg/linter/test_data/rules/camel_case_types.dart b/pkg/linter/test_data/rules/camel_case_types.dart
index ae8d4b6..98097e0 100644
--- a/pkg/linter/test_data/rules/camel_case_types.dart
+++ b/pkg/linter/test_data/rules/camel_case_types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N camel_case_types`
-
 class A {}
 
 class DB {}
diff --git a/pkg/linter/test_data/rules/cascade_invocations.dart b/pkg/linter/test_data/rules/cascade_invocations.dart
index 8212f88..0844392 100644
--- a/pkg/linter/test_data/rules/cascade_invocations.dart
+++ b/pkg/linter/test_data/rules/cascade_invocations.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N cascade_invocations`
-
 import 'dart:math' as math;
 
 void alreadyDeclared() {
diff --git a/pkg/linter/test_data/rules/cast_nullable_to_non_nullable.dart b/pkg/linter/test_data/rules/cast_nullable_to_non_nullable.dart
index adc576a..403c04d 100644
--- a/pkg/linter/test_data/rules/cast_nullable_to_non_nullable.dart
+++ b/pkg/linter/test_data/rules/cast_nullable_to_non_nullable.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N cast_nullable_to_non_nullable`
-
 class A {}
 
 class B extends A {}
diff --git a/pkg/linter/test_data/rules/combinators_ordering.dart b/pkg/linter/test_data/rules/combinators_ordering.dart
index afd6ee3..d15a553 100644
--- a/pkg/linter/test_data/rules/combinators_ordering.dart
+++ b/pkg/linter/test_data/rules/combinators_ordering.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N combinators_ordering`
-
 import 'dart:math' as m1 show max, min; // OK
 import 'dart:math' as m2 show min, max; // LINT
 
diff --git a/pkg/linter/test_data/rules/constant_identifier_names.dart b/pkg/linter/test_data/rules/constant_identifier_names.dart
index 4caf5be..bd06cb0 100644
--- a/pkg/linter/test_data/rules/constant_identifier_names.dart
+++ b/pkg/linter/test_data/rules/constant_identifier_names.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N constant_identifier_names`
-
 const DEFAULT_TIMEOUT = 1000; //LINT
 const PI = 3.14; //LINT
 
diff --git a/pkg/linter/test_data/rules/control_flow_in_finally.dart b/pkg/linter/test_data/rules/control_flow_in_finally.dart
index 8a92735..50ab8ae 100644
--- a/pkg/linter/test_data/rules/control_flow_in_finally.dart
+++ b/pkg/linter/test_data/rules/control_flow_in_finally.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N control_flow_in_finally`
-
 class Ok {
   double compliantMethod() {
     var i = 5.0;
diff --git a/pkg/linter/test_data/rules/curly_braces_in_flow_control_structures.dart b/pkg/linter/test_data/rules/curly_braces_in_flow_control_structures.dart
index fb44e54..dc290b8 100644
--- a/pkg/linter/test_data/rules/curly_braces_in_flow_control_structures.dart
+++ b/pkg/linter/test_data/rules/curly_braces_in_flow_control_structures.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N curly_braces_in_flow_control_structures`
-
 testIfElse() {
   if (false) return; // OK
 
diff --git a/pkg/linter/test_data/rules/deprecated_consistency.dart b/pkg/linter/test_data/rules/deprecated_consistency.dart
index 5667838..0e3500f 100644
--- a/pkg/linter/test_data/rules/deprecated_consistency.dart
+++ b/pkg/linter/test_data/rules/deprecated_consistency.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N deprecated_consistency`
-
 @deprecated
 class A {
   A.ko(); // LINT
diff --git a/pkg/linter/test_data/rules/eol_at_end_of_file.dart b/pkg/linter/test_data/rules/eol_at_end_of_file.dart
index 0f56b6d..050c825 100644
--- a/pkg/linter/test_data/rules/eol_at_end_of_file.dart
+++ b/pkg/linter/test_data/rules/eol_at_end_of_file.dart
@@ -2,7 +2,5 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N eol_at_end_of_file`
-
 bar() {
 } //LINT
\ No newline at end of file
diff --git a/pkg/linter/test_data/rules/hash_and_equals.dart b/pkg/linter/test_data/rules/hash_and_equals.dart
index 5945427..2dead85 100644
--- a/pkg/linter/test_data/rules/hash_and_equals.dart
+++ b/pkg/linter/test_data/rules/hash_and_equals.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N hash_and_equals`
-
 class Bad {
   final int value;
   Bad(this.value);
diff --git a/pkg/linter/test_data/rules/implicit_call_tearoffs.dart b/pkg/linter/test_data/rules/implicit_call_tearoffs.dart
index 663f3ae..a3af80a 100644
--- a/pkg/linter/test_data/rules/implicit_call_tearoffs.dart
+++ b/pkg/linter/test_data/rules/implicit_call_tearoffs.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N implicit_call_tearoffs`
-
 class C {
   void call() {}
   void other() {}
diff --git a/pkg/linter/test_data/rules/iterable_contains_unrelated_type.dart b/pkg/linter/test_data/rules/iterable_contains_unrelated_type.dart
index fa05527..4b8119d 100644
--- a/pkg/linter/test_data/rules/iterable_contains_unrelated_type.dart
+++ b/pkg/linter/test_data/rules/iterable_contains_unrelated_type.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N iterable_contains_unrelated_type`
-
 // TODO(https://github.com/dart-lang/linter/issues/4143): Use 3.0.0
 // @dart=2.19
 
diff --git a/pkg/linter/test_data/rules/library_prefixes.dart b/pkg/linter/test_data/rules/library_prefixes.dart
index e1672d0..8b497f0 100644
--- a/pkg/linter/test_data/rules/library_prefixes.dart
+++ b/pkg/linter/test_data/rules/library_prefixes.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N library_prefixes`
-
 import 'dart:async' as _async; //OK
 import 'dart:collection' as $collection; //OK
 import 'dart:convert' as _1; //LINT
diff --git a/pkg/linter/test_data/rules/library_private_types_in_public_api.dart b/pkg/linter/test_data/rules/library_private_types_in_public_api.dart
index dc27983..00bdea5 100644
--- a/pkg/linter/test_data/rules/library_private_types_in_public_api.dart
+++ b/pkg/linter/test_data/rules/library_private_types_in_public_api.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N library_private_types_in_public_api`
-
 // Top level functions
 
 String f1(int i) => '';
diff --git a/pkg/linter/test_data/rules/lines_longer_than_80_chars.dart b/pkg/linter/test_data/rules/lines_longer_than_80_chars.dart
index 4c9b805..cbfd949 100644
--- a/pkg/linter/test_data/rules/lines_longer_than_80_chars.dart
+++ b/pkg/linter/test_data/rules/lines_longer_than_80_chars.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N lines_longer_than_80_chars`
-
 var short = 'This is a short line'; // OK
 var line80 =
     '                                                                   '; // OK
diff --git a/pkg/linter/test_data/rules/list_remove_unrelated_type.dart b/pkg/linter/test_data/rules/list_remove_unrelated_type.dart
index 2045360..a1da7b7 100644
--- a/pkg/linter/test_data/rules/list_remove_unrelated_type.dart
+++ b/pkg/linter/test_data/rules/list_remove_unrelated_type.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N list_remove_unrelated_type`
-
 void someFunction() {
   var list = <int>[];
   if (list.remove('1')) print('someFunction'); // LINT
diff --git a/pkg/linter/test_data/rules/literal_only_boolean_expressions.dart b/pkg/linter/test_data/rules/literal_only_boolean_expressions.dart
index 63f7154..7b500c1 100644
--- a/pkg/linter/test_data/rules/literal_only_boolean_expressions.dart
+++ b/pkg/linter/test_data/rules/literal_only_boolean_expressions.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N literal_only_boolean_expressions`
-
 // ignore_for_file: dead_code
 
 bool variable = true;
diff --git a/pkg/linter/test_data/rules/no_default_cases.dart b/pkg/linter/test_data/rules/no_default_cases.dart
index 923bc79..c257d7e 100644
--- a/pkg/linter/test_data/rules/no_default_cases.dart
+++ b/pkg/linter/test_data/rules/no_default_cases.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N no_default_cases`
-
 // Enum-like
 class EL {
   final int i;
diff --git a/pkg/linter/test_data/rules/no_leading_underscores_for_library_prefixes.dart b/pkg/linter/test_data/rules/no_leading_underscores_for_library_prefixes.dart
index 043cfa2..f1f5984 100644
--- a/pkg/linter/test_data/rules/no_leading_underscores_for_library_prefixes.dart
+++ b/pkg/linter/test_data/rules/no_leading_underscores_for_library_prefixes.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N no_leading_underscores_for_library_prefixes`
-
 import 'dart:async' as _async; // LINT
 import 'dart:convert' as _convert; // LINT
 import 'dart:core' as dart_core; // OK
diff --git a/pkg/linter/test_data/rules/no_leading_underscores_for_local_identifiers.dart b/pkg/linter/test_data/rules/no_leading_underscores_for_local_identifiers.dart
index 16e6fbf..83ba965 100644
--- a/pkg/linter/test_data/rules/no_leading_underscores_for_local_identifiers.dart
+++ b/pkg/linter/test_data/rules/no_leading_underscores_for_local_identifiers.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N no_leading_underscores_for_local_identifiers`
-
 /// https://github.com/dart-lang/linter/issues/3360
 int _g() { // OK (not local)
   int _bar() { // LINT
diff --git a/pkg/linter/test_data/rules/non_constant_identifier_names.dart b/pkg/linter/test_data/rules/non_constant_identifier_names.dart
index cc35181..87c88a1 100644
--- a/pkg/linter/test_data/rules/non_constant_identifier_names.dart
+++ b/pkg/linter/test_data/rules/non_constant_identifier_names.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N non_constant_identifier_names`
-
 // ignore_for_file: unused_local_variable, unused_element, unused_field
 
 void main() {
diff --git a/pkg/linter/test_data/rules/omit_local_variable_types.dart b/pkg/linter/test_data/rules/omit_local_variable_types.dart
index 5c4e77e..395b304 100644
--- a/pkg/linter/test_data/rules/omit_local_variable_types.dart
+++ b/pkg/linter/test_data/rules/omit_local_variable_types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N omit_local_variable_types`
-
 // ignore_for_file: prefer_foreach, unused_local_variable
 
 f() {
diff --git a/pkg/linter/test_data/rules/overridden_fields.dart b/pkg/linter/test_data/rules/overridden_fields.dart
index 68dded4..969994c 100644
--- a/pkg/linter/test_data/rules/overridden_fields.dart
+++ b/pkg/linter/test_data/rules/overridden_fields.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N overridden_fields`
-
 class Base {
   Object field = 'lorem';
 
diff --git a/pkg/linter/test_data/rules/package_api_docs.dart b/pkg/linter/test_data/rules/package_api_docs.dart
index 5448b6c..62b7d92 100644
--- a/pkg/linter/test_data/rules/package_api_docs.dart
+++ b/pkg/linter/test_data/rules/package_api_docs.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N package_api_docs`
-
 abstract class Foo //__LINT => TODO: fix API Model to treat tests specially
 {
   /// Start a bar.
diff --git a/pkg/linter/test_data/rules/package_prefixed_library_names.dart b/pkg/linter/test_data/rules/package_prefixed_library_names.dart
index bcd0820..6fa5c49 100644
--- a/pkg/linter/test_data/rules/package_prefixed_library_names.dart
+++ b/pkg/linter/test_data/rules/package_prefixed_library_names.dart
@@ -2,7 +2,5 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N package_prefixed_library_names`
-
 // See: https://github.com/dart-lang/linter/issues/3395
 library linter.not_where_it_should_be; //FAILING
diff --git a/pkg/linter/test_data/rules/prefer_asserts_in_initializer_lists.dart b/pkg/linter/test_data/rules/prefer_asserts_in_initializer_lists.dart
index 2df7132..bf0cd0a 100644
--- a/pkg/linter/test_data/rules/prefer_asserts_in_initializer_lists.dart
+++ b/pkg/linter/test_data/rules/prefer_asserts_in_initializer_lists.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_asserts_in_initializer_lists`
-
 get tlg => null;
 tlm() => null;
 
diff --git a/pkg/linter/test_data/rules/prefer_asserts_with_message.dart b/pkg/linter/test_data/rules/prefer_asserts_with_message.dart
index c2f8141..525467e 100644
--- a/pkg/linter/test_data/rules/prefer_asserts_with_message.dart
+++ b/pkg/linter/test_data/rules/prefer_asserts_with_message.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_asserts_with_message`
-
 m() {
   assert(true); // LINT
   assert(true, ''); // OK
diff --git a/pkg/linter/test_data/rules/prefer_collection_literals.dart b/pkg/linter/test_data/rules/prefer_collection_literals.dart
index ec01589f..9983e8c7 100644
--- a/pkg/linter/test_data/rules/prefer_collection_literals.dart
+++ b/pkg/linter/test_data/rules/prefer_collection_literals.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_collection_literals`
-
 import 'dart:collection';
 
 //ignore_for_file: unused_local_variable
diff --git a/pkg/linter/test_data/rules/prefer_conditional_assignment.dart b/pkg/linter/test_data/rules/prefer_conditional_assignment.dart
index ab5f524..ee77499 100644
--- a/pkg/linter/test_data/rules/prefer_conditional_assignment.dart
+++ b/pkg/linter/test_data/rules/prefer_conditional_assignment.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_conditional_assignment`
-
 String getFullUserName(Person person) {
   // Something expensive
   return '';
diff --git a/pkg/linter/test_data/rules/prefer_const_constructors_in_immutables.dart b/pkg/linter/test_data/rules/prefer_const_constructors_in_immutables.dart
index 320d071..27f382b 100644
--- a/pkg/linter/test_data/rules/prefer_const_constructors_in_immutables.dart
+++ b/pkg/linter/test_data/rules/prefer_const_constructors_in_immutables.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_const_constructors_in_immutables`
-
 import 'package:meta/meta.dart';
 
 @immutable
diff --git a/pkg/linter/test_data/rules/prefer_const_declarations.dart b/pkg/linter/test_data/rules/prefer_const_declarations.dart
index cc5d12b..0cc9dcd 100644
--- a/pkg/linter/test_data/rules/prefer_const_declarations.dart
+++ b/pkg/linter/test_data/rules/prefer_const_declarations.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_const_declarations`
-
 //ignore_for_file: unused_local_variable
 
 class C<T> {
diff --git a/pkg/linter/test_data/rules/prefer_const_literals_to_create_immutables.dart b/pkg/linter/test_data/rules/prefer_const_literals_to_create_immutables.dart
index 89a80b4..c0c7c75 100644
--- a/pkg/linter/test_data/rules/prefer_const_literals_to_create_immutables.dart
+++ b/pkg/linter/test_data/rules/prefer_const_literals_to_create_immutables.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_const_literals_to_create_immutables`
-
 import 'package:meta/meta.dart';
 
 @immutable
diff --git a/pkg/linter/test_data/rules/prefer_expression_function_bodies.dart b/pkg/linter/test_data/rules/prefer_expression_function_bodies.dart
index 7d4fa15..f7e6792 100644
--- a/pkg/linter/test_data/rules/prefer_expression_function_bodies.dart
+++ b/pkg/linter/test_data/rules/prefer_expression_function_bodies.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_expression_function_bodies`
-
 int bad() { // LINT
   return 1;
 }
diff --git a/pkg/linter/test_data/rules/prefer_final_fields.dart b/pkg/linter/test_data/rules/prefer_final_fields.dart
index 1761072..0abde54 100644
--- a/pkg/linter/test_data/rules/prefer_final_fields.dart
+++ b/pkg/linter/test_data/rules/prefer_final_fields.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_final_fields`
-
 //ignore_for_file: unused_field, unused_local_variable, prefer_expression_function_bodies
 
 class PrefixOps {
diff --git a/pkg/linter/test_data/rules/prefer_if_null_operators.dart b/pkg/linter/test_data/rules/prefer_if_null_operators.dart
index 2380228..c3fa044 100644
--- a/pkg/linter/test_data/rules/prefer_if_null_operators.dart
+++ b/pkg/linter/test_data/rules/prefer_if_null_operators.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_if_null_operators`
-
 var v;
 
 m(p) {
diff --git a/pkg/linter/test_data/rules/prefer_initializing_formals.dart b/pkg/linter/test_data/rules/prefer_initializing_formals.dart
index 3c912e2..919cd1b 100644
--- a/pkg/linter/test_data/rules/prefer_initializing_formals.dart
+++ b/pkg/linter/test_data/rules/prefer_initializing_formals.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_initializing_formals`
-
 class D {
   /// https://github.com/dart-lang/linter/issues/2664
   D(int initialValue) : value = initialValue;
diff --git a/pkg/linter/test_data/rules/prefer_int_literals.dart b/pkg/linter/test_data/rules/prefer_int_literals.dart
index 4fe8866..3d45f80 100644
--- a/pkg/linter/test_data/rules/prefer_int_literals.dart
+++ b/pkg/linter/test_data/rules/prefer_int_literals.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_int_literals`
-
 import 'dart:math';
 
 const double okDouble = 7.3; // OK
diff --git a/pkg/linter/test_data/rules/prefer_is_empty.dart b/pkg/linter/test_data/rules/prefer_is_empty.dart
index 1189492..4de5702 100644
--- a/pkg/linter/test_data/rules/prefer_is_empty.dart
+++ b/pkg/linter/test_data/rules/prefer_is_empty.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_is_empty`
-
 const l = '';
 const bool empty = l.length == 0; //OK
 
diff --git a/pkg/linter/test_data/rules/prefer_is_not_empty.dart b/pkg/linter/test_data/rules/prefer_is_not_empty.dart
index 888d6bd..febc139 100644
--- a/pkg/linter/test_data/rules/prefer_is_not_empty.dart
+++ b/pkg/linter/test_data/rules/prefer_is_not_empty.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_is_not_empty`
-
 bool lne = ![1].isEmpty; // LINT [12:12]
 bool mne = !{2: 'a'}.isEmpty; // LINT
 bool ine = !iterable.isEmpty; // LINT
diff --git a/pkg/linter/test_data/rules/prefer_is_not_operator.dart b/pkg/linter/test_data/rules/prefer_is_not_operator.dart
index 1e365ae..2a57295 100644
--- a/pkg/linter/test_data/rules/prefer_is_not_operator.dart
+++ b/pkg/linter/test_data/rules/prefer_is_not_operator.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_is_not_operator`
-
 class Foo {}
 var _a;
 
diff --git a/pkg/linter/test_data/rules/prefer_void_to_null.dart b/pkg/linter/test_data/rules/prefer_void_to_null.dart
index 1de5b25..9ec9392 100644
--- a/pkg/linter/test_data/rules/prefer_void_to_null.dart
+++ b/pkg/linter/test_data/rules/prefer_void_to_null.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N prefer_void_to_null`
-
 // TODO(mfairhurst) test void with a prefix, except that causes bugs.
 // TODO(mfairhurst) test defining a class named Null (requires a 2nd file)
 
diff --git a/pkg/linter/test_data/rules/require_trailing_commas.dart b/pkg/linter/test_data/rules/require_trailing_commas.dart
index 8c4e344..829e06c 100644
--- a/pkg/linter/test_data/rules/require_trailing_commas.dart
+++ b/pkg/linter/test_data/rules/require_trailing_commas.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N require_trailing_commas`
-
 class RequireTrailingCommasExample {
   RequireTrailingCommasExample.constructor1(Object param1, Object param2);
 
diff --git a/pkg/linter/test_data/rules/type_init_formals.dart b/pkg/linter/test_data/rules/type_init_formals.dart
index cff3008..12681a8 100644
--- a/pkg/linter/test_data/rules/type_init_formals.dart
+++ b/pkg/linter/test_data/rules/type_init_formals.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N type_init_formals`
-
 class Good {
   String name;
   Good(this.name); // OK
diff --git a/pkg/linter/test_data/rules/unawaited_futures.dart b/pkg/linter/test_data/rules/unawaited_futures.dart
index 480d5cb..ce0e420 100644
--- a/pkg/linter/test_data/rules/unawaited_futures.dart
+++ b/pkg/linter/test_data/rules/unawaited_futures.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unawaited_futures`
-
 import 'dart:async';
 
 Future fut() => Future.value(0);
diff --git a/pkg/linter/test_data/rules/unnecessary_brace_in_string_interps.dart b/pkg/linter/test_data/rules/unnecessary_brace_in_string_interps.dart
index 4ab4456..3750c878 100644
--- a/pkg/linter/test_data/rules/unnecessary_brace_in_string_interps.dart
+++ b/pkg/linter/test_data/rules/unnecessary_brace_in_string_interps.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unnecessary_brace_in_string_interps`
-
 main(args) {
   print('hello');
   print('hello $args');
diff --git a/pkg/linter/test_data/rules/unnecessary_lambdas.dart b/pkg/linter/test_data/rules/unnecessary_lambdas.dart
index a13977e..850658a 100644
--- a/pkg/linter/test_data/rules/unnecessary_lambdas.dart
+++ b/pkg/linter/test_data/rules/unnecessary_lambdas.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unnecessary_lambdas`
-
 // ignore: avoid_annotating_with_dynamic
 typedef F = int Function(dynamic s);
 
diff --git a/pkg/linter/test_data/rules/unnecessary_overrides.dart b/pkg/linter/test_data/rules/unnecessary_overrides.dart
index 68f1130..2def60a 100644
--- a/pkg/linter/test_data/rules/unnecessary_overrides.dart
+++ b/pkg/linter/test_data/rules/unnecessary_overrides.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unnecessary_overrides`
-
 import 'package:meta/meta.dart';
 
 class _MyAnnotation {
diff --git a/pkg/linter/test_data/rules/unnecessary_parenthesis.dart b/pkg/linter/test_data/rules/unnecessary_parenthesis.dart
index dd8628d..5cdf714 100644
--- a/pkg/linter/test_data/rules/unnecessary_parenthesis.dart
+++ b/pkg/linter/test_data/rules/unnecessary_parenthesis.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unnecessary_parenthesis`
-
 import 'dart:async';
 
 /// https://github.com/dart-lang/linter/issues/2944
diff --git a/pkg/linter/test_data/rules/unnecessary_statements.dart b/pkg/linter/test_data/rules/unnecessary_statements.dart
index 1570466..7a4799f 100644
--- a/pkg/linter/test_data/rules/unnecessary_statements.dart
+++ b/pkg/linter/test_data/rules/unnecessary_statements.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unnecessary_statements`
-
 void constructorTearOffs() {
   MyClass.new; // LINT
   MyClass.named; // LINT
diff --git a/pkg/linter/test_data/rules/unrelated_type_equality_checks.dart b/pkg/linter/test_data/rules/unrelated_type_equality_checks.dart
index 2eeeef0..f1e1648 100644
--- a/pkg/linter/test_data/rules/unrelated_type_equality_checks.dart
+++ b/pkg/linter/test_data/rules/unrelated_type_equality_checks.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N unrelated_type_equality_checks`
-
 void someFunction() {
   var x = '1';
   if (x == 1) print('someFunction'); // LINT
diff --git a/pkg/linter/test_data/rules/void_checks.dart b/pkg/linter/test_data/rules/void_checks.dart
index 5bcae8f..b0de6ce 100644
--- a/pkg/linter/test_data/rules/void_checks.dart
+++ b/pkg/linter/test_data/rules/void_checks.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// test w/ `dart test -N void_checks`
-
 // @dart=2.9
 
 // ignore_for_file: unused_local_variable
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index 2b34434..356d86c 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/field_promotability.dart';
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
 import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -246,4 +247,8 @@
   DecoratedType variableType(PromotableElement variable) {
     return _variableRepository!.decoratedElementType(variable);
   }
+
+  @override
+  PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(Object property) =>
+      null;
 }
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index bec7bd1..6de1861 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -14,7 +14,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.100';
+const String version = '1.101';
 
 // Restriction on statements and expressions.
 const int stmtDepth = 1;
@@ -119,8 +119,30 @@
     }
   }
 
+  void emitFunctionAnnotations() {
+    if (fuzzer.rollDice(6)) {
+      fuzzer.emitLn('@pragma("vm:always-consider-inlining")');
+    }
+    if (fuzzer.rollDice(6)) {
+      fuzzer.emitLn('@pragma("vm:entry-point")');
+    }
+    if (fuzzer.rollDice(6)) {
+      fuzzer.emitLn('@pragma("vm:never-inline")');
+    }
+    if (fuzzer.rollDice(6)) {
+      fuzzer.emitLn('@pragma("vm:prefer-inline")');
+    }
+    if (fuzzer.rollDice(10)) {
+      fuzzer.emit('@pragma(');
+      fuzzer.emitString();
+      fuzzer.emit(')');
+      fuzzer.emitNewline();
+    }
+  }
+
   void emitFunctionDefinition() {
     final type = returnType.dartName;
+    emitFunctionAnnotations();
     fuzzer.emitLn('$type $name', newline: false);
     fuzzer.emitParenWrapped(() => fuzzer.emitParDecls(parameters));
     emitFunctionBody();
diff --git a/runtime/vm/compiler/assembler/assembler_arm_test.cc b/runtime/vm/compiler/assembler/assembler_arm_test.cc
index 5c57e41..7a2e0ff 100644
--- a/runtime/vm/compiler/assembler/assembler_arm_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm_test.cc
@@ -3921,6 +3921,17 @@
   EXPECT_EQ(kMintCid, result);
 }
 
+static void EnterTestFrame(Assembler* assembler) {
+  __ EnterFrame(1 << THR | 1 << PP | 1 << CODE_REG, 0);
+  __ MoveRegister(CODE_REG, R0);
+  __ MoveRegister(THR, R1);
+  __ LoadPoolPointer(PP);
+}
+
+static void LeaveTestFrame(Assembler* assembler) {
+  __ LeaveFrame(1 << THR | 1 << PP | 1 << CODE_REG);
+}
+
 #define LOAD_FROM_BOX_TEST(VALUE, SAME_REGISTER)                               \
   ASSEMBLER_TEST_GENERATE(LoadWordFromBoxOrSmi##VALUE##SAME_REGISTER,          \
                           assembler) {                                         \
@@ -3930,25 +3941,32 @@
         same_register ? src : CallingConventions::ArgumentRegisters[1];        \
     const intptr_t value = VALUE;                                              \
                                                                                \
+    EnterTestFrame(assembler);                                                 \
+                                                                               \
     __ LoadObject(src, Integer::ZoneHandle(Integer::New(value, Heap::kOld)));  \
     __ LoadWordFromBoxOrSmi(dst, src);                                         \
     __ MoveRegister(CallingConventions::kReturnReg, dst);                      \
                                                                                \
+    LeaveTestFrame(assembler);                                                 \
+                                                                               \
     __ Ret();                                                                  \
   }                                                                            \
                                                                                \
   ASSEMBLER_TEST_RUN(LoadWordFromBoxOrSmi##VALUE##SAME_REGISTER, test) {       \
-    const intptr_t res = test->Invoke<intptr_t, intptr_t>(0x0);                \
-    EXPECT_EQ(static_cast<intptr_t>(VALUE), res);                              \
+    const int64_t res = test->InvokeWithCodeAndThread<int64_t>();              \
+    EXPECT_EQ(static_cast<intptr_t>(VALUE), static_cast<intptr_t>(res));       \
   }
 
 LOAD_FROM_BOX_TEST(0, true)
 LOAD_FROM_BOX_TEST(0, false)
 LOAD_FROM_BOX_TEST(1, true)
 LOAD_FROM_BOX_TEST(1, false)
+LOAD_FROM_BOX_TEST(0x7FFFFFFF, true)
+LOAD_FROM_BOX_TEST(0x7FFFFFFF, false)
+LOAD_FROM_BOX_TEST(0x80000000, true)
+LOAD_FROM_BOX_TEST(0x80000000, false)
 LOAD_FROM_BOX_TEST(0xFFFFFFFF, true)
 LOAD_FROM_BOX_TEST(0xFFFFFFFF, false)
-// TODO(https://dartbug.com/53622): Add tests with Mints.
 
 }  // namespace compiler
 }  // namespace dart
diff --git a/runtime/vm/compiler/assembler/assembler_riscv_test.cc b/runtime/vm/compiler/assembler/assembler_riscv_test.cc
index 9746ab0..e3328cb 100644
--- a/runtime/vm/compiler/assembler/assembler_riscv_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_riscv_test.cc
@@ -7711,6 +7711,24 @@
   EXPECT_EQ(kMintCid, result);
 }
 
+static void EnterTestFrame(Assembler* assembler) {
+  __ EnterFrame(0);
+  __ PushRegister(CODE_REG);
+  __ PushRegister(THR);
+  __ PushRegister(PP);
+  __ MoveRegister(CODE_REG, A0);
+  __ MoveRegister(THR, A1);
+  __ LoadPoolPointer(PP);
+}
+
+static void LeaveTestFrame(Assembler* assembler) {
+  __ PopRegister(PP);
+  __ PopRegister(THR);
+  __ PopRegister(CODE_REG);
+
+  __ LeaveFrame();
+}
+
 #define LOAD_FROM_BOX_TEST(VALUE, SAME_REGISTER)                               \
   ASSEMBLER_TEST_GENERATE(LoadWordFromBoxOrSmi##VALUE##SAME_REGISTER,          \
                           assembler) {                                         \
@@ -7720,16 +7738,20 @@
         same_register ? src : CallingConventions::ArgumentRegisters[1];        \
     const intptr_t value = VALUE;                                              \
                                                                                \
+    EnterTestFrame(assembler);                                                 \
+                                                                               \
     __ LoadObject(src, Integer::ZoneHandle(Integer::New(value, Heap::kOld)));  \
     __ LoadWordFromBoxOrSmi(dst, src);                                         \
     __ MoveRegister(CallingConventions::kReturnReg, dst);                      \
                                                                                \
+    LeaveTestFrame(assembler);                                                 \
+                                                                               \
     __ Ret();                                                                  \
   }                                                                            \
                                                                                \
   ASSEMBLER_TEST_RUN(LoadWordFromBoxOrSmi##VALUE##SAME_REGISTER, test) {       \
-    const intptr_t res = test->Invoke<intptr_t, intptr_t>(0x0);                \
-    EXPECT_EQ(static_cast<intptr_t>(VALUE), res);                              \
+    const int64_t res = test->InvokeWithCodeAndThread<int64_t>();              \
+    EXPECT_EQ(static_cast<intptr_t>(VALUE), static_cast<intptr_t>(res));       \
   }
 
 LOAD_FROM_BOX_TEST(0, true)
@@ -7737,13 +7759,20 @@
 LOAD_FROM_BOX_TEST(1, true)
 LOAD_FROM_BOX_TEST(1, false)
 #if defined(TARGET_ARCH_RISCV32)
+LOAD_FROM_BOX_TEST(0x7FFFFFFF, true)
+LOAD_FROM_BOX_TEST(0x7FFFFFFF, false)
+LOAD_FROM_BOX_TEST(0x80000000, true)
+LOAD_FROM_BOX_TEST(0x80000000, false)
 LOAD_FROM_BOX_TEST(0xFFFFFFFF, true)
 LOAD_FROM_BOX_TEST(0xFFFFFFFF, false)
 #else
+LOAD_FROM_BOX_TEST(0x7FFFFFFFFFFFFFFF, true)
+LOAD_FROM_BOX_TEST(0x7FFFFFFFFFFFFFFF, false)
+LOAD_FROM_BOX_TEST(0x8000000000000000, true)
+LOAD_FROM_BOX_TEST(0x8000000000000000, false)
 LOAD_FROM_BOX_TEST(0xFFFFFFFFFFFFFFFF, true)
 LOAD_FROM_BOX_TEST(0xFFFFFFFFFFFFFFFF, false)
 #endif
-// TODO(https://dartbug.com/53622): Add tests with Mints.
 
 }  // namespace compiler
 }  // namespace dart
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index 0b67527..fb7137e 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -256,22 +256,26 @@
       Tag integer_tag = reader.ReadTag(&payload);  // read tag.
       switch (integer_tag) {
         case kBigIntLiteral: {
+          reader.ReadPosition();
           const String& value = H.DartString(reader.ReadStringReference());
           instance = Integer::New(value, Heap::kOld);
           break;
         }
         case kSpecializedIntLiteral: {
+          reader.ReadPosition();
           const int64_t value =
               static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
           instance = Integer::New(value, Heap::kOld);
           break;
         }
         case kNegativeIntLiteral: {
+          reader.ReadPosition();
           const int64_t value = -static_cast<int64_t>(reader.ReadUInt());
           instance = Integer::New(value, Heap::kOld);
           break;
         }
         case kPositiveIntLiteral: {
+          reader.ReadPosition();
           const int64_t value = reader.ReadUInt();
           instance = Integer::New(value, Heap::kOld);
           break;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 28fdd94..c144eb2 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3696,6 +3696,7 @@
     switch (PeekTag()) {
       case kStringLiteral: {
         ReadTag();
+        ReadPosition();
         const String& s = H.DartSymbolPlain(ReadStringReference());
         // Skip empty strings.
         if (!s.Equals("")) {
@@ -3976,6 +3977,7 @@
 
 Fragment StreamingFlowGraphBuilder::BuildThisExpression(
     TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   return LoadLocal(parsed_function()->receiver_var());
@@ -4254,6 +4256,7 @@
 
 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
     TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   const String& value =
@@ -4270,6 +4273,7 @@
 
 Fragment StreamingFlowGraphBuilder::BuildStringLiteral(
     TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   return Constant(H.DartSymbolPlain(
@@ -4278,6 +4282,7 @@
 
 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(uint8_t payload,
                                                     TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   int64_t value = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
@@ -4286,6 +4291,7 @@
 
 Fragment StreamingFlowGraphBuilder::BuildIntLiteral(bool is_negative,
                                                     TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   int64_t value = is_negative ? -static_cast<int64_t>(ReadUInt())
@@ -4295,6 +4301,7 @@
 
 Fragment StreamingFlowGraphBuilder::BuildDoubleLiteral(
     TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   Double& constant = Double::ZoneHandle(
@@ -4304,12 +4311,14 @@
 
 Fragment StreamingFlowGraphBuilder::BuildBoolLiteral(bool value,
                                                      TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   return Constant(Bool::Get(value));
 }
 
 Fragment StreamingFlowGraphBuilder::BuildNullLiteral(TokenPosition* position) {
+  ReadPosition();  // ignore file offset.
   if (position != nullptr) *position = TokenPosition::kNoSource;
 
   return Constant(Instance::ZoneHandle(Z, Instance::null()));
@@ -5466,6 +5475,9 @@
   ASSERT(block_expression_depth() == 0);  // no try-catch in block-expr
   InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch");
 
+  const TokenPosition pos = ReadPosition();  // read position.
+  if (position != nullptr) *position = pos;
+
   intptr_t try_handler_index = AllocateTryIndex();
   Fragment try_body = TryCatch(try_handler_index);
   JoinEntryInstr* after_try = BuildJoinEntry();
@@ -5591,6 +5603,9 @@
 
   InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally");
 
+  const TokenPosition pos = ReadPosition();  // read position.
+  if (position != nullptr) *position = pos;
+
   // There are 5 different cases where we need to execute the finally block:
   //
   //  a) 1/2/3th case: Special control flow going out of `node->body()`:
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index de5ba12..6e34218 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -571,6 +571,7 @@
       CalculateDartTypeFingerprint();  // read type.
       return;
     case kThisExpression:
+      ReadPosition();  // read position.
       return;
     case kRethrow:
       ReadPosition();  // read position.
@@ -636,20 +637,26 @@
       CalculateListOfDartTypesFingerprint();  // read type arguments.
       return;
     case kBigIntLiteral:
+      ReadPosition();                         // read position.
       CalculateStringReferenceFingerprint();  // read string reference.
       return;
     case kStringLiteral:
+      ReadPosition();                         // read position.
       CalculateStringReferenceFingerprint();  // read string reference.
       return;
     case kSpecializedIntLiteral:
+      ReadPosition();  // read position.
       return;
     case kNegativeIntLiteral:
+      ReadPosition();         // read position.
       BuildHash(ReadUInt());  // read value.
       return;
     case kPositiveIntLiteral:
+      ReadPosition();         // read position.
       BuildHash(ReadUInt());  // read value.
       return;
     case kDoubleLiteral: {
+      ReadPosition();               // read position.
       double value = ReadDouble();  // read value.
       uint64_t data = bit_cast<uint64_t>(value);
       BuildHash(static_cast<uint32_t>(data >> 32));
@@ -657,10 +664,13 @@
       return;
     }
     case kTrueLiteral:
+      ReadPosition();  // read position.
       return;
     case kFalseLiteral:
+      ReadPosition();  // read position.
       return;
     case kNullLiteral:
+      ReadPosition();  // read position.
       return;
     case kConstantExpression:
       ReadPosition();
@@ -803,6 +813,7 @@
       return;
     }
     case kTryCatch: {
+      ReadPosition();                           // read position.
       CalculateStatementFingerprint();          // read body.
       BuildHash(ReadByte());                    // read flags
       intptr_t catch_count = ReadListLength();  // read number of catches.
@@ -824,6 +835,7 @@
       return;
     }
     case kTryFinally:
+      ReadPosition();                   // read position.
       CalculateStatementFingerprint();  // read body.
       CalculateStatementFingerprint();  // read finalizer.
       return;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 12baae4..9dff13a 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2667,6 +2667,7 @@
       SkipDartType();  // read type.
       return;
     case kThisExpression:
+      ReadPosition();  // read position.
       return;
     case kRethrow:
       ReadPosition();  // read position.
@@ -2732,27 +2733,36 @@
       SkipListOfDartTypes();  // read type arguments.
       return;
     case kBigIntLiteral:
+      ReadPosition();         // read position.
       SkipStringReference();  // read string reference.
       return;
     case kStringLiteral:
+      ReadPosition();         // read position.
       SkipStringReference();  // read string reference.
       return;
     case kSpecializedIntLiteral:
+      ReadPosition();  // read position.
       return;
     case kNegativeIntLiteral:
-      ReadUInt();  // read value.
+      ReadPosition();  // read position.
+      ReadUInt();      // read value.
       return;
     case kPositiveIntLiteral:
-      ReadUInt();  // read value.
+      ReadPosition();  // read position.
+      ReadUInt();      // read value.
       return;
     case kDoubleLiteral:
-      ReadDouble();  // read value.
+      ReadPosition();  // read position.
+      ReadDouble();    // read value.
       return;
     case kTrueLiteral:
+      ReadPosition();  // read position.
       return;
     case kFalseLiteral:
+      ReadPosition();  // read position.
       return;
     case kNullLiteral:
+      ReadPosition();  // read position.
       return;
     case kConstantExpression:
       ReadPosition();  // read position.
@@ -2893,6 +2903,7 @@
       return;
     }
     case kTryCatch: {
+      ReadPosition();                           // read position
       SkipStatement();                          // read body.
       ReadByte();                               // read flags
       intptr_t catch_count = ReadListLength();  // read number of catches.
@@ -2912,6 +2923,7 @@
       return;
     }
     case kTryFinally:
+      ReadPosition();   // read position
       SkipStatement();  // read body.
       SkipStatement();  // read finalizer.
       return;
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index c7e2cf7..dbbb4bf 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -848,6 +848,7 @@
       return;
     case kThisExpression:
       HandleLoadReceiver();
+      helper_.ReadPosition();  // read file offset.
       return;
     case kRethrow:
       helper_.ReadPosition();  // read position.
@@ -933,27 +934,36 @@
       return;
     }
     case kBigIntLiteral:
+      helper_.ReadPosition();         // read position.
       helper_.SkipStringReference();  // read string reference.
       return;
     case kStringLiteral:
+      helper_.ReadPosition();         // read position.
       helper_.SkipStringReference();  // read string reference.
       return;
     case kSpecializedIntLiteral:
+      helper_.ReadPosition();  // read position.
       return;
     case kNegativeIntLiteral:
-      helper_.ReadUInt();  // read value.
+      helper_.ReadPosition();  // read position.
+      helper_.ReadUInt();      // read value.
       return;
     case kPositiveIntLiteral:
-      helper_.ReadUInt();  // read value.
+      helper_.ReadPosition();  // read position.
+      helper_.ReadUInt();      // read value.
       return;
     case kDoubleLiteral:
-      helper_.ReadDouble();  // read value.
+      helper_.ReadPosition();  // read position.
+      helper_.ReadDouble();    // read value.
       return;
     case kTrueLiteral:
+      helper_.ReadPosition();  // read position.
       return;
     case kFalseLiteral:
+      helper_.ReadPosition();  // read position.
       return;
     case kNullLiteral:
+      helper_.ReadPosition();  // read position.
       return;
     case kConstantExpression:
       helper_.ReadPosition();
@@ -1175,7 +1185,8 @@
     case kTryCatch: {
       ++depth_.try_;
       AddTryVariables();
-      VisitStatement();  // read body.
+      helper_.ReadPosition();  // read position.
+      VisitStatement();        // read body.
       --depth_.try_;
 
       ++depth_.catch_;
@@ -1216,7 +1227,8 @@
       ++depth_.finally_;
       AddTryVariables();
 
-      VisitStatement();  // read body.
+      helper_.ReadPosition();  // read position.
+      VisitStatement();        // read body.
 
       --depth_.finally_;
       --depth_.try_;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index c82c433..7dad31f 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -18,7 +18,7 @@
 // package:kernel/binary.md.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kSupportedKernelFormatVersion = 110;
+static const uint32_t kSupportedKernelFormatVersion = 111;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index e5e8367..bd051cf 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -50,6 +50,7 @@
     Tag tag = helper_->ReadTag(&payload);  // read tag.
     switch (tag) {
       case kBigIntLiteral: {
+        helper_->ReadPosition();
         const String& literal_str =
             H.DartString(helper_->ReadStringReference(),
                          Heap::kOld);  // read index into string table.
@@ -63,10 +64,12 @@
         return true;
       }
       case kStringLiteral:
+        helper_->ReadPosition();
         simple_value_ = &H.DartSymbolPlain(
             helper_->ReadStringReference());  // read index into string table.
         return true;
       case kSpecializedIntLiteral:
+        helper_->ReadPosition();
         simple_value_ =
             &Integer::ZoneHandle(Z, Integer::New(static_cast<int32_t>(payload) -
                                                      SpecializedIntLiteralBias,
@@ -74,29 +77,35 @@
         *simple_value_ = H.Canonicalize(*simple_value_);
         return true;
       case kNegativeIntLiteral:
+        helper_->ReadPosition();
         simple_value_ = &Integer::ZoneHandle(
             Z, Integer::New(-static_cast<int64_t>(helper_->ReadUInt()),
                             Heap::kOld));  // read value.
         *simple_value_ = H.Canonicalize(*simple_value_);
         return true;
       case kPositiveIntLiteral:
+        helper_->ReadPosition();
         simple_value_ = &Integer::ZoneHandle(
             Z, Integer::New(static_cast<int64_t>(helper_->ReadUInt()),
                             Heap::kOld));  // read value.
         *simple_value_ = H.Canonicalize(*simple_value_);
         return true;
       case kDoubleLiteral:
+        helper_->ReadPosition();
         simple_value_ = &Double::ZoneHandle(
             Z, Double::New(helper_->ReadDouble(), Heap::kOld));  // read value.
         *simple_value_ = H.Canonicalize(*simple_value_);
         return true;
       case kTrueLiteral:
+        helper_->ReadPosition();
         simple_value_ = &Bool::Handle(Z, Bool::Get(true).ptr());
         return true;
       case kFalseLiteral:
+        helper_->ReadPosition();
         simple_value_ = &Bool::Handle(Z, Bool::Get(false).ptr());
         return true;
       case kNullLiteral:
+        helper_->ReadPosition();
         simple_value_ = &Instance::ZoneHandle(Z, Instance::null());
         return true;
       default:
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index d264b87..b31cd71 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -533,13 +533,9 @@
 // ArgNType is the type of the Nth argument.
 #if defined(USING_SIMULATOR)
 
-#if defined(ARCH_IS_64_BIT)
-  // TODO(fschneider): Make InvokeWithCodeAndThread<> more general and work on
-  // 32-bit.
   // Since Simulator::Call always return a int64_t, bit_cast does not work
-  // on 32-bit platforms when returning an int32_t. Since template functions
-  // don't support partial specialization, we'd need to introduce a helper
-  // class to support 32-bit return types.
+  // on 32-bit platforms when returning an int32_t. Use static cast on the
+  // call site in 32-bit to get rid of the upper bits if needed.
   template <typename ResultType>
   ResultType InvokeWithCodeAndThread() {
     const bool fp_return = is_double<ResultType>::value;
@@ -563,7 +559,6 @@
         reinterpret_cast<intptr_t>(thread), reinterpret_cast<intptr_t>(arg1), 0,
         fp_return, fp_args));
   }
-#endif  // ARCH_IS_64_BIT
 
   template <typename ResultType, typename Arg1Type>
   ResultType Invoke(Arg1Type arg1) {
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index ab25b95..b82bac3 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -693,26 +693,27 @@
             // See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.4
             _removeTrailingSpaces(_headerValue);
             String headerValue = String.fromCharCodes(_headerValue);
-            const errorIfBothText = "Both Content-Length and Transfer-Encoding "
-                "are specified, at most one is allowed";
+
+            // RFC-7230 3.3.3 says:
+            // If a message is received with both a Transfer-Encoding and a
+            // Content-Length header field, the Transfer-Encoding overrides
+            // the Content-Length...
+            // A sender MUST remove the received Content-Length field prior
+            // to forwarding such a message downstream.
             if (headerField == HttpHeaders.contentLengthHeader) {
-              // Content Length header should not have more than one occurrence
-              // or coexist with Transfer Encoding header.
+              // Content Length header should not have more than one occurrence.
               if (_contentLength) {
                 throw HttpException("The Content-Length header occurred "
                     "more than once, at most one is allowed.");
-              } else if (_transferEncoding) {
-                throw HttpException(errorIfBothText);
+              } else if (!_transferEncoding) {
+                _contentLength = true;
               }
-              _contentLength = true;
             } else if (headerField == HttpHeaders.transferEncodingHeader) {
               _transferEncoding = true;
               if (_caseInsensitiveCompare("chunked".codeUnits, _headerValue)) {
                 _chunked = true;
               }
-              if (_contentLength) {
-                throw HttpException(errorIfBothText);
-              }
+              _contentLength = false;
             }
             var headers = _headers!;
             if (headerField == HttpHeaders.connectionHeader) {
@@ -730,7 +731,10 @@
                 }
                 headers._add(headerField, tokens[i]);
               }
-            } else {
+            } else if (headerField != HttpHeaders.contentLengthHeader ||
+                !_transferEncoding) {
+              // Calling `headers._add("transfer-encoding", "chunked")` will
+              // remove the Content-Length header.
               headers._add(headerField, headerValue);
             }
             _headerField.clear();
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index d2c5c11..be125ae 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -302,6 +302,8 @@
     documented: false,
     platforms: DART2JS_PLATFORM,
   ),
+  "_wasm": const LibraryInfo('_wasm/wasm_types.dart',
+      categories: '', documented: false),
 };
 
 /// Information about a "dart:" library.
diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
index 135bbb1..5d02b6a 100644
--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart
@@ -227,16 +227,34 @@
   _NativeCallableBase(this._pointer);
 
   @override
-  Pointer<NativeFunction<T>> get nativeFunction => _pointer;
+  Pointer<NativeFunction<T>> get nativeFunction {
+    if (_isClosed) {
+      throw StateError("NativeCallable is already closed.");
+    }
+    return _pointer;
+  }
 
   @override
   void close() {
-    if (_pointer == nullptr) {
-      throw StateError("NativeCallable is already closed.");
+    if (!_isClosed) {
+      _deleteNativeCallable(_pointer);
+      _pointer = nullptr;
     }
-    _deleteNativeCallable(_pointer);
-    _pointer = nullptr;
   }
+
+  @override
+  void set keepIsolateAlive(bool value) {
+    if (!_isClosed) {
+      _setKeepIsolateAlive(value);
+    }
+  }
+
+  @override
+  bool get keepIsolateAlive => _isClosed ? false : _getKeepIsolateAlive();
+
+  void _setKeepIsolateAlive(bool value);
+  bool _getKeepIsolateAlive();
+  bool get _isClosed => _pointer == nullptr;
 }
 
 final class _NativeCallableIsolateLocal<T extends Function>
@@ -252,13 +270,6 @@
   }
 
   @override
-  void set keepIsolateAlive(bool value) {
-    if (_pointer == nullptr) {
-      throw StateError("NativeCallable is already closed.");
-    }
-    _setKeepIsolateAlive(value);
-  }
-
   void _setKeepIsolateAlive(bool value) {
     if (_keepIsolateAlive != value) {
       _keepIsolateAlive = value;
@@ -267,7 +278,7 @@
   }
 
   @override
-  bool get keepIsolateAlive => _keepIsolateAlive;
+  bool _getKeepIsolateAlive() => _keepIsolateAlive;
 }
 
 final class _NativeCallableListener<T extends Function>
@@ -286,12 +297,12 @@
   }
 
   @override
-  void set keepIsolateAlive(bool value) {
+  void _setKeepIsolateAlive(bool value) {
     _port.keepIsolateAlive = value;
   }
 
   @override
-  bool get keepIsolateAlive => _port.keepIsolateAlive;
+  bool _getKeepIsolateAlive() => _port.keepIsolateAlive;
 }
 
 @patch
diff --git a/sdk/lib/_internal/wasm/lib/wasm_types_patch.dart b/sdk/lib/_internal/wasm/lib/wasm_types_patch.dart
new file mode 100644
index 0000000..208c3f9
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/wasm_types_patch.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:_internal" show patch;
+import "dart:_js_helper";
+import "dart:_wasm";
+import "dart:js_interop";
+
+@patch
+extension WasmExternRefToJSAny on WasmExternRef {
+  @patch
+  JSAny get toJS => JSValue.box(this) as JSAny;
+}
+
+@patch
+WasmExternRef? externRefForJSAny(JSAny object) =>
+    (object as JSValue).toExternRef;
diff --git a/sdk/lib/_wasm/wasm_types.dart b/sdk/lib/_wasm/wasm_types.dart
index 8d4aba1..1933e54 100644
--- a/sdk/lib/_wasm/wasm_types.dart
+++ b/sdk/lib/_wasm/wasm_types.dart
@@ -4,6 +4,8 @@
 
 library dart._wasm;
 
+import 'dart:js_interop';
+
 // A collection a special Dart types that are mapped directly to Wasm types
 // by the dart2wasm compiler. These types have a number of constraints:
 //
@@ -280,3 +282,12 @@
   WasmF32 toWasmF32() => WasmF32.fromDouble(this);
   WasmF64 toWasmF64() => WasmF64.fromDouble(this);
 }
+
+extension WasmExternRefToJSAny on WasmExternRef {
+  external JSAny get toJS;
+}
+
+// Note: We would make this an extension method on JSAny, but external methods
+// on JS interop types are assumed to be JS interop functions, not methods that
+// are patched in patch files. So instead we just use a plain function here.
+external WasmExternRef? externRefForJSAny(JSAny object);
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 756e493..ea01f64 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -270,15 +270,15 @@
   /// The native function pointer which can be used to invoke the `callback`
   /// passed to the constructor.
   ///
-  /// If this receiver has been [close]d, the pointer is a [nullptr].
+  /// This pointer must not be read after the callable has been [close]d.
   Pointer<NativeFunction<T>> get nativeFunction;
 
   /// Closes this callback and releases its resources.
   ///
   /// Further calls to existing [nativeFunction]s will result in undefined
-  /// behavior. New accesses to [nativeFunction] will give a [nullptr].
+  /// behavior.
   ///
-  /// This method must not be called more than once on each native callback.
+  /// Subsequent calls to [close] will be ignored.
   ///
   /// It is safe to call [close] inside the [callback].
   void close();
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index aa5bb1a..ab8cecd 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -270,7 +270,8 @@
         "uri": "_internal/wasm/lib/string_helper.dart"
       },
       "_wasm": {
-        "uri": "_wasm/wasm_types.dart"
+        "uri": "_wasm/wasm_types.dart",
+        "patches": "_internal/wasm/lib/wasm_types_patch.dart"
       },
       "async": {
         "uri": "async/async.dart",
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index f211365..795d78c 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -227,6 +227,7 @@
       uri: _internal/wasm/lib/string_helper.dart
     _wasm:
       uri: _wasm/wasm_types.dart
+      patches: _internal/wasm/lib/wasm_types_patch.dart
     async:
       uri: async/async.dart
       patches:
diff --git a/tests/ffi/async_void_function_callbacks_test.dart b/tests/ffi/async_void_function_callbacks_test.dart
index c755d1f..7ae6373 100644
--- a/tests/ffi/async_void_function_callbacks_test.dart
+++ b/tests/ffi/async_void_function_callbacks_test.dart
@@ -89,10 +89,15 @@
   final callback = NativeCallable<CallbackNativeType>.listener(simpleFunction);
   Expect.notEquals(nullptr, callback.nativeFunction);
   callback.close();
-  Expect.equals(nullptr, callback.nativeFunction);
+
   Expect.throwsStateError(() {
-    callback.close();
+    final _ = callback.nativeFunction;
   });
+
+  // Expect that these do not throw.
+  callback.close();
+  callback.keepIsolateAlive = true;
+  Expect.isFalse(callback.keepIsolateAlive);
 }
 
 Future<void> testNativeCallableUseAfterFree() async {
@@ -129,7 +134,9 @@
   Expect.equals(1123, await simpleFunctionResult.future);
 
   // The callback is already closed.
-  Expect.equals(nullptr, simpleFunctionAndCloseSelf_callable!.nativeFunction);
+  Expect.throwsStateError(() {
+    final _ = simpleFunctionAndCloseSelf_callable!.nativeFunction;
+  });
 }
 
 void simpleFunctionThrows(int a, int b) {
diff --git a/tests/ffi/isolate_local_function_callbacks_test.dart b/tests/ffi/isolate_local_function_callbacks_test.dart
index 9b49fc2..5b582e5 100644
--- a/tests/ffi/isolate_local_function_callbacks_test.dart
+++ b/tests/ffi/isolate_local_function_callbacks_test.dart
@@ -84,10 +84,15 @@
       exceptionalReturn: 0);
   Expect.notEquals(nullptr, callback.nativeFunction);
   callback.close();
-  Expect.equals(nullptr, callback.nativeFunction);
+
   Expect.throwsStateError(() {
-    callback.close();
+    final _ = callback.nativeFunction;
   });
+
+  // Expect that these do not throw.
+  callback.close();
+  callback.keepIsolateAlive = true;
+  Expect.isFalse(callback.keepIsolateAlive);
 }
 
 late NativeCallable selfClosingStaticCallback;
@@ -105,7 +110,9 @@
       callTwoIntFunction(selfClosingStaticCallback.nativeFunction, 1000, 234));
 
   // The callback is already closed.
-  Expect.equals(nullptr, selfClosingStaticCallback.nativeFunction);
+  Expect.throwsStateError(() {
+    final _ = selfClosingStaticCallback.nativeFunction;
+  });
 }
 
 testNativeCallableNestedCloseCallClosure() {
@@ -122,7 +129,9 @@
   Expect.equals(1234, callTwoIntFunction(callback.nativeFunction, 1000, 234));
 
   // The callback is already closed.
-  Expect.equals(nullptr, callback.nativeFunction);
+  Expect.throwsStateError(() {
+    final _ = callback.nativeFunction;
+  });
 }
 
 int throwerCallback(int a, int b) {
diff --git a/tests/language/extension_type/regress_53607_test.dart b/tests/language/extension_type/regress_53607_test.dart
new file mode 100644
index 0000000..30eebe1
--- /dev/null
+++ b/tests/language/extension_type/regress_53607_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2023, 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.
+
+// SharedOptions=--enable-experiment=inline-class
+
+// Test for issue https://github.com/dart-lang/sdk/issues/53607
+
+// All kinds of named constructors, including a primary constructor,
+// and getters "conflicting" with them.
+extension type const Ext1.name0(int i) {
+  Ext1.name1(this.i);
+  Ext1.name2(int i): this.name0(i);
+  factory Ext1.name3(int i) = Ext1.name0;
+  factory Ext1.name4(int i) => Ext1.name0(i);
+
+  const Ext1.name5(this.i);
+  const Ext1.name6(int i): this.name0(i);
+  const factory Ext1.name7(int i) = Ext1.name0;
+
+  int get name0 => i;
+  int get name1 => i;
+  int get name2 => i;
+  int get name3 => i;
+  int get name4 => i;
+  int get name5 => i;
+  int get name6 => i;
+  int get name7 => i;
+}
+
+class C {
+  int get name3 => 0;
+  set name4(int i) {}
+  int name5() => 0;
+}
+
+// Other instance members with same name as constructors,
+// both extension and interface members.
+extension type const Ext2.name0(C _) implements C {
+  Ext2.name1(): this.name0(C());
+  Ext2.name2(): this.name0(C());
+  Ext2.name3(): this.name0(C());
+  Ext2.name4(): this.name0(C());
+  Ext2.name5(): this.name0(C());
+
+  int get name0 => 0;
+  set name1(int i) {}
+  int name2() => 0;
+}
+
+
+void main() {
+  Ext1 e = Ext1.name0(0);
+  var res = [
+    e.name0,
+    e.name1,
+    e.name2,
+    e.name3,
+    e.name4,
+    e.name5,
+    e.name6,
+    e.name7,
+  ];
+  if (res.length != 8) throw AssertionError("Sanity check failed");
+
+  Ext2 c = Ext2.name0(C());
+  var res2 = [
+    c.name0,
+    c.name1 = 0,
+    c.name2(),
+    c.name3,
+    c.name4 = 0,
+    c.name5(),
+  ];
+  if (res2.length != 6) throw AssertionError("Sanity check failed");
+}
diff --git a/tests/language/inference_update_2/why_not_promoted_error_test.dart b/tests/language/inference_update_2/why_not_promoted_error_test.dart
new file mode 100644
index 0000000..5318529
--- /dev/null
+++ b/tests/language/inference_update_2/why_not_promoted_error_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, 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.
+
+// Tests that the appropriate "why not promoted" context messages are shown when
+// field promotion fails.
+
+// SharedOptions=--enable-experiment=inference-update-2
+
+class C {
+  int? get _privateGetter => publicField;
+  //       ^^^^^^^^^^^^^^
+  // [context 1] '_privateGetter' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 4] '_privateGetter' refers to a getter so it couldn't be promoted.
+  final int? publicField;
+  //         ^^^^^^^^^^^
+  // [context 2] 'publicField' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 5] 'publicField' refers to a public field so it couldn't be promoted.
+  int? _nonFinalField;
+  //   ^^^^^^^^^^^^^^
+  // [context 3] '_nonFinalField' refers to a non-final field so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-final-field
+  // [context 6] '_nonFinalField' refers to a non-final field so it couldn't be promoted.
+  C(int? i)
+      : publicField = i,
+        _nonFinalField = i;
+}
+
+void notAField(C c) {
+  if (c._privateGetter != null) {
+    c._privateGetter.isEven;
+    //               ^^^^^^
+    // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+    // [cfe 4] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+void notPrivate(C c) {
+  if (c.publicField != null) {
+    c.publicField.isEven;
+    //            ^^^^^^
+    // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+    // [cfe 5] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+void notFinal(C c) {
+  if (c._nonFinalField != null) {
+    c._nonFinalField.isEven;
+    //               ^^^^^^
+    // [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+    // [cfe 6] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+main() {}
diff --git a/tests/language/inference_update_2/why_not_promoted_external_error_test.dart b/tests/language/inference_update_2/why_not_promoted_external_error_test.dart
new file mode 100644
index 0000000..9767997
--- /dev/null
+++ b/tests/language/inference_update_2/why_not_promoted_external_error_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2023, 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.
+
+// Tests that the appropriate "why not promoted" context messages are shown when
+// field promotion fails due to the presence of an external field.
+//
+// This test is in its own file since it fails under some implementations due to
+// lack of a binding for the external field.
+
+// SharedOptions=--enable-experiment=inference-update-2
+
+class C {
+  external final int? _i;
+  //                  ^^
+  // [context 1] '_i' refers to an external field so it couldn't be promoted.  See http://dart.dev/go/non-promo-external-field
+  // [context 2] '_i' refers to an external field so it couldn't be promoted.
+  // [web] Only JS interop members may be 'external'.
+}
+
+void test(C c) {
+  if (c._i != null) {
+    c._i.isEven;
+    //   ^^^^^^
+    // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+    // [cfe 2] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+  }
+}
+
+main() {}
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 15617c6..889a7ec 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -7,6 +7,7 @@
 async_star/async_star_await_for_test: Skip # evades flake detection https://github.com/dart-lang/sdk/issues/51086
 external_abstract_fields/external_fields_test: SkipByDesign # Non-JS-interop external members are not supported
 inference_update_2/external_field_test: SkipByDesign # Non-JS-interop external members are not supported
+inference_update_2/why_not_promoted_external_error_test: SkipByDesign # Non-JS-interop external members are not supported
 mixin_method_override_test/G5: Skip # Issue 34354
 number/int64_literal_runtime*_test: Skip # This is testing Dart 2.0 int64 semantics
 vm/*: SkipByDesign # Tests for the VM.
diff --git a/tests/language/language_dart2wasm.status b/tests/language/language_dart2wasm.status
index 404aaa5..9af854a 100644
--- a/tests/language/language_dart2wasm.status
+++ b/tests/language/language_dart2wasm.status
@@ -4,6 +4,7 @@
 # Sections in this file should contain "$compiler == dart2wasm".
 
 [ $compiler == dart2wasm ]
+inference_update_2/why_not_promoted_external_error_test: SkipByDesign # Non-JS-interop external members are not supported
 number/web_int_literals_test: SkipByDesign # WASM has real integers.
 vm/*: SkipByDesign # Tests for the VM.
 
diff --git a/tests/language/language_dartdevc.status b/tests/language/language_dartdevc.status
index cfc69e9..10d518f 100644
--- a/tests/language/language_dartdevc.status
+++ b/tests/language/language_dartdevc.status
@@ -9,6 +9,7 @@
 async_star/throw_in_catch_test: Skip # Times out. Issue 29920
 external_abstract_fields/external_fields_test: SkipByDesign # Non-JS-interop external members are not supported
 inference_update_2/external_field_test: SkipByDesign # Non-JS-interop external members are not supported
+inference_update_2/why_not_promoted_external_error_test: SkipByDesign # Non-JS-interop external members are not supported
 number/int64_literal_runtime*_test: Skip # This is testing Dart 2.0 int64 semantics.
 superinterface_variance/*: Skip # Issue dart-lang/language#113
 vm/*: SkipByDesign # VM only tests.; VM only tests.
diff --git a/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart b/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
index 1ee9ec6..77b66aa 100644
--- a/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
+++ b/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
@@ -9,8 +9,8 @@
 class C1 {
   int? bad;
   //   ^^^
-  // [context 21] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 50] 'bad' refers to a property so it couldn't be promoted.
+  // [context 1] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 50] 'bad' refers to a public field so it couldn't be promoted.
   f(int i) {}
 }
 
@@ -18,7 +18,7 @@
   if (c.bad == null) return;
   c.f(c.bad);
   //  ^^^^^
-  // [analyzer 21] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 1] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //    ^
   // [cfe 50] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -26,8 +26,8 @@
 class C2 {
   int? bad;
   //   ^^^
-  // [context 43] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 51] 'bad' refers to a property so it couldn't be promoted.
+  // [context 2] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 51] 'bad' refers to a public field so it couldn't be promoted.
   f([int i = 0]) {}
 }
 
@@ -35,7 +35,7 @@
   if (c.bad == null) return;
   c.f(c.bad);
   //  ^^^^^
-  // [analyzer 43] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 2] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //    ^
   // [cfe 51] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -43,8 +43,8 @@
 class C3 {
   int? bad;
   //   ^^^
-  // [context 9] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 52] 'bad' refers to a property so it couldn't be promoted.
+  // [context 3] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 52] 'bad' refers to a public field so it couldn't be promoted.
   f({required int i}) {}
 }
 
@@ -52,7 +52,7 @@
   if (c.bad == null) return;
   c.f(i: c.bad);
   //     ^^^^^
-  // [analyzer 9] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 3] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 52] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -60,8 +60,8 @@
 class C4 {
   int? bad;
   //   ^^^
-  // [context 17] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 53] 'bad' refers to a property so it couldn't be promoted.
+  // [context 4] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 53] 'bad' refers to a public field so it couldn't be promoted.
   f({int i = 0}) {}
 }
 
@@ -69,7 +69,7 @@
   if (c.bad == null) return;
   c.f(i: c.bad);
   //     ^^^^^
-  // [analyzer 17] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 4] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 53] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -77,8 +77,8 @@
 class C5 {
   List<int>? bad;
   //         ^^^
-  // [context 39] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 54] 'bad' refers to a property so it couldn't be promoted.
+  // [context 5] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 54] 'bad' refers to a public field so it couldn't be promoted.
   f<T>(List<T> x) {}
 }
 
@@ -86,7 +86,7 @@
   if (c.bad == null) return;
   c.f(c.bad);
   //  ^^^^^
-  // [analyzer 39] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 5] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //    ^
   // [cfe 54] The argument type 'List<int>?' can't be assigned to the parameter type 'List<int>' because 'List<int>?' is nullable and 'List<int>' isn't.
 }
@@ -94,8 +94,8 @@
 class C6 {
   int? bad;
   //   ^^^
-  // [context 5] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 55] 'bad' refers to a property so it couldn't be promoted.
+  // [context 6] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 55] 'bad' refers to a public field so it couldn't be promoted.
   C6(int i);
 }
 
@@ -103,7 +103,7 @@
   if (c.bad == null) return null;
   return C6(c.bad);
   //        ^^^^^
-  // [analyzer 5] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 6] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //          ^
   // [cfe 55] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -111,8 +111,8 @@
 class C7 {
   int? bad;
   //   ^^^
-  // [context 25] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 56] 'bad' refers to a property so it couldn't be promoted.
+  // [context 7] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 56] 'bad' refers to a public field so it couldn't be promoted.
   C7(int i);
 }
 
@@ -120,7 +120,7 @@
   if (c.bad == null) return null;
   return new C7(c.bad);
   //            ^^^^^
-  // [analyzer 25] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 7] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //              ^
   // [cfe 56] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -128,15 +128,15 @@
 class C8 {
   int? bad;
   //   ^^^
-  // [context 35] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 57] 'bad' refers to a property so it couldn't be promoted.
+  // [context 8] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 57] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 userDefinableBinaryOpRhs(C8 c) {
   if (c.bad == null) return;
   1 + c.bad;
   //  ^^^^^
-  // [analyzer 35] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 8] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //    ^
   // [cfe 57] A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
 }
@@ -180,10 +180,10 @@
 class C11 {
   bool? bad;
   //    ^^^
-  // [context 15] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 19] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 58] 'bad' refers to a property so it couldn't be promoted.
-  // [context 59] 'bad' refers to a property so it couldn't be promoted.
+  // [context 9] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 10] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 58] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 59] 'bad' refers to a public field so it couldn't be promoted.
   f(bool b) {}
 }
 
@@ -191,12 +191,12 @@
   if (c.bad == null) return;
   c.f(c.bad && b);
   //  ^^^^^
-  // [analyzer 19] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 9] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //    ^
   // [cfe 58] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   c.f(b && c.bad);
   //       ^^^^^
-  // [analyzer 15] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 10] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //         ^
   // [cfe 59] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -204,10 +204,10 @@
 class C12 {
   bool? bad;
   //    ^^^
-  // [context 6] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 37] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 60] 'bad' refers to a property so it couldn't be promoted.
-  // [context 61] 'bad' refers to a property so it couldn't be promoted.
+  // [context 11] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 12] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 60] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 61] 'bad' refers to a public field so it couldn't be promoted.
   f(bool b) {}
 }
 
@@ -215,12 +215,12 @@
   if (c.bad == null) return;
   c.f(c.bad || b);
   //  ^^^^^
-  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 11] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //    ^
   // [cfe 60] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   c.f(b || c.bad);
   //       ^^^^^
-  // [analyzer 37] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 12] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //         ^
   // [cfe 61] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -228,15 +228,15 @@
 class C13 {
   bool? bad;
   //    ^^^
-  // [context 3] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 62] 'bad' refers to a property so it couldn't be promoted.
+  // [context 13] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 62] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 assertStatementCondition(C13 c) {
   if (c.bad == null) return;
   assert(c.bad);
   //     ^^^^^
-  // [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 13] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //       ^
   // [cfe 62] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -244,13 +244,13 @@
 class C14 {
   bool? bad;
   //    ^^^
-  // [context 10] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 63] 'bad' refers to a property so it couldn't be promoted.
+  // [context 14] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 63] 'bad' refers to a public field so it couldn't be promoted.
   C14.assertInitializerCondition(C14 c)
       : bad = c.bad!,
         assert(c.bad);
         //     ^^^^^
-        // [analyzer 10] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+        // [analyzer 14] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
         //       ^
         // [cfe 63] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -258,8 +258,8 @@
 class C15 {
   bool? bad;
   //    ^^^
-  // [context 49] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 64] 'bad' refers to a property so it couldn't be promoted.
+  // [context 15] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 64] 'bad' refers to a public field so it couldn't be promoted.
   f(bool b) {}
 }
 
@@ -267,7 +267,7 @@
   if (c.bad == null) return;
   c.f(!c.bad);
   //   ^^^^^
-  // [analyzer 49] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 15] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //     ^
   // [cfe 64] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -275,36 +275,36 @@
 class C16 {
   bool? bad;
   //    ^^^
-  // [context 11] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 12] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 16] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 20] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 65] 'bad' refers to a property so it couldn't be promoted.
-  // [context 66] 'bad' refers to a property so it couldn't be promoted.
-  // [context 67] 'bad' refers to a property so it couldn't be promoted.
-  // [context 68] 'bad' refers to a property so it couldn't be promoted.
+  // [context 16] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 17] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 18] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 19] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 65] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 66] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 67] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 68] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 forLoopCondition(C16 c) {
   if (c.bad == null) return;
   for (; c.bad;) {}
   //     ^^^^^
-  // [analyzer 12] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 16] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //       ^
   // [cfe 65] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   [for (; c.bad;) null];
   //      ^^^^^
-  // [analyzer 20] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 17] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //        ^
   // [cfe 66] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   ({for (; c.bad;) null});
   //       ^^^^^
-  // [analyzer 16] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 18] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //         ^
   // [cfe 67] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   ({for (; c.bad;) null: null});
   //       ^^^^^
-  // [analyzer 11] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 19] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //         ^
   // [cfe 68] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -312,8 +312,8 @@
 class C17 {
   bool? bad;
   //    ^^^
-  // [context 33] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 69] 'bad' refers to a property so it couldn't be promoted.
+  // [context 20] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 69] 'bad' refers to a public field so it couldn't be promoted.
   f(int i) {}
 }
 
@@ -321,7 +321,7 @@
   if (c.bad == null) return;
   c.f(c.bad ? 1 : 2);
   //  ^^^^^
-  // [analyzer 33] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 20] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //    ^
   // [cfe 69] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -329,15 +329,15 @@
 class C18 {
   bool? bad;
   //    ^^^
-  // [context 8] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 70] 'bad' refers to a property so it couldn't be promoted.
+  // [context 21] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 70] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 doLoopCondition(C18 c) {
   if (c.bad == null) return;
   do {} while (c.bad);
   //           ^^^^^
-  // [analyzer 8] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 21] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //             ^
   // [cfe 70] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -345,36 +345,36 @@
 class C19 {
   bool? bad;
   //    ^^^
-  // [context 13] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 23] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 28] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 30] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 71] 'bad' refers to a property so it couldn't be promoted.
-  // [context 72] 'bad' refers to a property so it couldn't be promoted.
-  // [context 73] 'bad' refers to a property so it couldn't be promoted.
-  // [context 74] 'bad' refers to a property so it couldn't be promoted.
+  // [context 22] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 23] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 24] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 25] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 71] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 72] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 73] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 74] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 ifCondition(C19 c) {
   if (c.bad == null) return;
   if (c.bad) {}
   //  ^^^^^
-  // [analyzer 23] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 22] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //    ^
   // [cfe 71] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   [if (c.bad) null];
   //   ^^^^^
-  // [analyzer 30] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 23] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //     ^
   // [cfe 72] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   ({if (c.bad) null});
   //    ^^^^^
-  // [analyzer 28] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 24] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //      ^
   // [cfe 73] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
   ({if (c.bad) null: null});
   //    ^^^^^
-  // [analyzer 13] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 25] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //      ^
   // [cfe 74] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -382,15 +382,15 @@
 class C20 {
   bool? bad;
   //    ^^^
-  // [context 22] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 75] 'bad' refers to a property so it couldn't be promoted.
+  // [context 26] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 75] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 whileCondition(C20 c) {
   if (c.bad == null) return;
   while (c.bad) {}
   //     ^^^^^
-  // [analyzer 22] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 26] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //       ^
   // [cfe 75] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
 }
@@ -398,15 +398,15 @@
 class C21 {
   int? bad;
   //   ^^^
-  // [context 46] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 76] 'bad' refers to a property so it couldn't be promoted.
+  // [context 27] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 76] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 assignmentRhs(C21 c, int i) {
   if (c.bad == null) return;
   i = c.bad;
   //  ^^^^^
-  // [analyzer 46] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 27] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //    ^
   // [cfe 76] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -414,15 +414,15 @@
 class C22 {
   int? bad;
   //   ^^^
-  // [context 44] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 77] 'bad' refers to a property so it couldn't be promoted.
+  // [context 28] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 77] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 variableInitializer(C22 c) {
   if (c.bad == null) return;
   int i = c.bad;
   //      ^^^^^
-  // [analyzer 44] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 28] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //        ^
   // [cfe 77] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -430,15 +430,15 @@
 class C23 {
   int? bad;
   //   ^^^
-  // [context 26] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 78] 'bad' refers to a property so it couldn't be promoted.
+  // [context 29] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 78] 'bad' refers to a public field so it couldn't be promoted.
   final int x;
   final int y;
   C23.constructorInitializer(C23 c)
       : x = c.bad!,
         y = c.bad;
         //  ^^^^^
-        // [analyzer 26] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
+        // [analyzer 29] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
         //    ^
         // [cfe 78] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -446,36 +446,36 @@
 class C24 {
   int? bad;
   //   ^^^
-  // [context 4] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 34] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 36] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 38] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 79] 'bad' refers to a property so it couldn't be promoted.
-  // [context 80] 'bad' refers to a property so it couldn't be promoted.
-  // [context 81] 'bad' refers to a property so it couldn't be promoted.
-  // [context 82] 'bad' refers to a property so it couldn't be promoted.
+  // [context 30] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 31] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 32] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 33] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 79] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 80] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 81] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 82] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 forVariableInitializer(C24 c) {
   if (c.bad == null) return;
   for (int i = c.bad; false;) {}
   //           ^^^^^
-  // [analyzer 36] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 30] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //             ^
   // [cfe 79] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   [for (int i = c.bad; false;) null];
   //            ^^^^^
-  // [analyzer 38] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 31] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //              ^
   // [cfe 80] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   ({for (int i = c.bad; false;) null});
   //             ^^^^^
-  // [analyzer 34] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 32] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //               ^
   // [cfe 81] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   ({for (int i = c.bad; false;) null: null});
   //             ^^^^^
-  // [analyzer 4] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 33] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //               ^
   // [cfe 82] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -483,36 +483,36 @@
 class C25 {
   int? bad;
   //   ^^^
-  // [context 31] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 40] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 41] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 45] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 83] 'bad' refers to a property so it couldn't be promoted.
-  // [context 84] 'bad' refers to a property so it couldn't be promoted.
-  // [context 85] 'bad' refers to a property so it couldn't be promoted.
-  // [context 86] 'bad' refers to a property so it couldn't be promoted.
+  // [context 34] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 35] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 36] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 37] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 83] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 84] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 85] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 86] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 forAssignmentInitializer(C25 c, int i) {
   if (c.bad == null) return;
   for (i = c.bad; false;) {}
   //       ^^^^^
-  // [analyzer 31] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 34] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //         ^
   // [cfe 83] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   [for (i = c.bad; false;) null];
   //        ^^^^^
-  // [analyzer 45] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 35] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //          ^
   // [cfe 84] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   ({for (i = c.bad; false;) null});
   //         ^^^^^
-  // [analyzer 40] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 36] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //           ^
   // [cfe 85] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   ({for (i = c.bad; false;) null: null});
   //         ^^^^^
-  // [analyzer 41] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 37] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //           ^
   // [cfe 86] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -520,8 +520,8 @@
 class C26 {
   int? bad;
   //   ^^^
-  // [context 27] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 87] 'bad' refers to a property so it couldn't be promoted.
+  // [context 38] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 87] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 compoundAssignmentRhs(C26 c) {
@@ -529,7 +529,7 @@
   if (c.bad == null) return;
   n += c.bad;
   //   ^^^^^
-  // [analyzer 27] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 38] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //     ^
   // [cfe 87] A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
 }
@@ -537,15 +537,15 @@
 class C27 {
   int? bad;
   //   ^^^
-  // [context 42] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 88] 'bad' refers to a property so it couldn't be promoted.
+  // [context 39] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 88] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexGet(C27 c, List<int> values) {
   if (c.bad == null) return;
   values[c.bad];
   //     ^^^^^
-  // [analyzer 42] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 39] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 88] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -553,15 +553,15 @@
 class C28 {
   int? bad;
   //   ^^^
-  // [context 7] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 89] 'bad' refers to a property so it couldn't be promoted.
+  // [context 40] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 89] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexSet(C28 c, List<int> values) {
   if (c.bad == null) return;
   values[c.bad] = 0;
   //     ^^^^^
-  // [analyzer 7] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 40] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 89] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -569,15 +569,15 @@
 class C29 {
   int? bad;
   //   ^^^
-  // [context 18] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 90] 'bad' refers to a property so it couldn't be promoted.
+  // [context 41] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 90] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexSetCompound(C29 c, List<int> values) {
   if (c.bad == null) return;
   values[c.bad] += 1;
   //     ^^^^^
-  // [analyzer 18] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 41] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 90] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -585,15 +585,15 @@
 class C30 {
   int? bad;
   //   ^^^
-  // [context 29] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 91] 'bad' refers to a property so it couldn't be promoted.
+  // [context 42] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 91] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexSetIfNull(C30 c, List<int?> values) {
   if (c.bad == null) return;
   values[c.bad] ??= 1;
   //     ^^^^^
-  // [analyzer 29] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 42] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 91] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -601,22 +601,22 @@
 class C31 {
   int? bad;
   //   ^^^
-  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 14] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 92] 'bad' refers to a property so it couldn't be promoted.
-  // [context 93] 'bad' refers to a property so it couldn't be promoted.
+  // [context 43] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 44] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 92] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 93] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexSetPreIncDec(C31 c, List<int> values) {
   if (c.bad == null) return;
   ++values[c.bad];
   //       ^^^^^
-  // [analyzer 14] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 43] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //         ^
   // [cfe 92] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   --values[c.bad];
   //       ^^^^^
-  // [analyzer 1] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 44] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //         ^
   // [cfe 93] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -624,22 +624,22 @@
 class C32 {
   int? bad;
   //   ^^^
-  // [context 32] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 48] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 94] 'bad' refers to a property so it couldn't be promoted.
-  // [context 95] 'bad' refers to a property so it couldn't be promoted.
+  // [context 45] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 46] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 94] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 95] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexSetPostIncDec(C32 c, List<int> values) {
   if (c.bad == null) return;
   values[c.bad]++;
   //     ^^^^^
-  // [analyzer 32] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 45] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 94] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
   values[c.bad]--;
   //     ^^^^^
-  // [analyzer 48] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [analyzer 46] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
   //       ^
   // [cfe 95] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -651,15 +651,15 @@
 class C33 {
   int? bad;
   //   ^^^
-  // [context 24] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 96] 'bad' refers to a property so it couldn't be promoted.
+  // [context 47] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 96] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 explicitExtensionInvocation(C33 c) {
   if (c.bad == null) return;
   E33(c.bad).f();
   //  ^^^^^
-  // [analyzer 24] COMPILE_TIME_ERROR.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE
+  // [analyzer 47] COMPILE_TIME_ERROR.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE
   //    ^
   // [cfe 96] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -667,8 +667,8 @@
 class C34 {
   int? bad;
   //   ^^^
-  // [context 47] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 97] 'bad' refers to a property so it couldn't be promoted.
+  // [context 48] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 97] 'bad' refers to a public field so it couldn't be promoted.
   C34(int value);
 }
 
@@ -678,7 +678,7 @@
       : other = c.bad!,
         super(c.bad);
         //    ^^^^^
-        // [analyzer 47] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+        // [analyzer 48] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
         //      ^
         // [cfe 97] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
 }
@@ -686,15 +686,15 @@
 class C35 {
   int? bad;
   //   ^^^
-  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 98] 'bad' refers to a property so it couldn't be promoted.
+  // [context 49] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 98] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 indexSetRhs(C35 c, List<int> x) {
   if (c.bad == null) return;
   x[0] = c.bad;
   //     ^^^^^
-  // [analyzer 2] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+  // [analyzer 49] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
   //       ^
   // [cfe 98] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
 }
diff --git a/tests/language/why_not_promoted/extension_property_error_test.dart b/tests/language/why_not_promoted/extension_property_error_test.dart
index d7de5cc..c3b5dcb 100644
--- a/tests/language/why_not_promoted/extension_property_error_test.dart
+++ b/tests/language/why_not_promoted/extension_property_error_test.dart
@@ -7,7 +7,7 @@
     if (this.i == null) return;
     this.i.isEven;
 //         ^^^^^^
-// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 6] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 
@@ -15,7 +15,7 @@
     if ((this).i == null) return;
     (this).i.isEven;
 //           ^^^^^^
-// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 7] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 
@@ -23,7 +23,7 @@
     if (i == null) return;
     i.isEven;
 //    ^^^^^^
-// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 }
@@ -31,16 +31,16 @@
 extension E on C {
   int? get i => null;
   //       ^
-  // [context 1] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 6] 'i' refers to a property so it couldn't be promoted.
-  // [context 7] 'i' refers to a property so it couldn't be promoted.
-  // [context 8] 'i' refers to a property so it couldn't be promoted.
-  // [context 9] 'i' refers to a property so it couldn't be promoted.
-  // [context 10] 'i' refers to a property so it couldn't be promoted.
+  // [context 1] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 2] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 3] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 4] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 5] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 6] 'i' refers to a getter so it couldn't be promoted.
+  // [context 7] 'i' refers to a getter so it couldn't be promoted.
+  // [context 8] 'i' refers to a getter so it couldn't be promoted.
+  // [context 9] 'i' refers to a getter so it couldn't be promoted.
+  // [context 10] 'i' refers to a getter so it couldn't be promoted.
   int? get j => null;
 }
 
@@ -49,7 +49,7 @@
     if (i == null) return;
     i.isEven;
 //    ^^^^^^
-// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 }
@@ -58,7 +58,7 @@
   if (c.i == null) return;
   c.i.isEven;
 //    ^^^^^^
-// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
 }
 
diff --git a/tests/language/why_not_promoted/field_error_test.dart b/tests/language/why_not_promoted/field_error_test.dart
index d010924..362a0c8 100644
--- a/tests/language/why_not_promoted/field_error_test.dart
+++ b/tests/language/why_not_promoted/field_error_test.dart
@@ -5,25 +5,25 @@
 class C {
   int? i;
   //   ^
-  // [context 1] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 6] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 7] 'i' refers to a property so it couldn't be promoted.
-  // [context 8] 'i' refers to a property so it couldn't be promoted.
-  // [context 9] 'i' refers to a property so it couldn't be promoted.
-  // [context 10] 'i' refers to a property so it couldn't be promoted.
-  // [context 11] 'i' refers to a property so it couldn't be promoted.
-  // [context 12] 'i' refers to a property so it couldn't be promoted.
+  // [context 1] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 2] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 3] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 4] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 5] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 6] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 7] 'i' refers to a public field so it couldn't be promoted.
+  // [context 8] 'i' refers to a public field so it couldn't be promoted.
+  // [context 9] 'i' refers to a public field so it couldn't be promoted.
+  // [context 10] 'i' refers to a public field so it couldn't be promoted.
+  // [context 11] 'i' refers to a public field so it couldn't be promoted.
+  // [context 12] 'i' refers to a public field so it couldn't be promoted.
   int? j;
 
   get_field_via_explicit_this() {
     if (this.i == null) return;
     this.i.isEven;
 //         ^^^^^^
-// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 7] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 
@@ -31,7 +31,7 @@
     if ((this).i == null) return;
     (this).i.isEven;
 //           ^^^^^^
-// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 
@@ -39,7 +39,7 @@
     if (i == null) return;
     i.isEven;
 //    ^^^^^^
-// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 }
@@ -57,7 +57,7 @@
     if (i == null) return;
     i.isEven;
 //    ^^^^^^
-// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 11] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 }
diff --git a/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart b/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
index ecf7b84..d012446 100644
--- a/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
+++ b/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
@@ -10,29 +10,29 @@
 class C1 {
   List<int>? bad;
   //         ^^^
-  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 4] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 5] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 6] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 7] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 8] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 9] 'bad' refers to a property so it couldn't be promoted.
-  // [context 10] 'bad' refers to a property so it couldn't be promoted.
-  // [context 11] 'bad' refers to a property so it couldn't be promoted.
-  // [context 12] 'bad' refers to a property so it couldn't be promoted.
-  // [context 13] 'bad' refers to a property so it couldn't be promoted.
-  // [context 14] 'bad' refers to a property so it couldn't be promoted.
-  // [context 15] 'bad' refers to a property so it couldn't be promoted.
-  // [context 16] 'bad' refers to a property so it couldn't be promoted.
+  // [context 1] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 2] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 3] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 4] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 5] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 6] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 7] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 8] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 9] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 10] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 11] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 12] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 13] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 14] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 15] 'bad' refers to a public field so it couldn't be promoted.
+  // [context 16] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 forStatement(C1 c) {
   if (c.bad == null) return;
   for (var x in c.bad) {}
   //            ^^^^^
-  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //              ^
   // [cfe 9] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
 }
@@ -41,7 +41,7 @@
   if (c.bad == null) return;
   [for (var x in c.bad) null];
   //             ^^^^^
-  // [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //               ^
   // [cfe 10] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
 }
@@ -59,7 +59,7 @@
   if (c.bad == null) return;
   <dynamic, dynamic>{for (var x in c.bad) null: null};
   //                               ^^^^^
-  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                                 ^
   // [cfe 12] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
 }
@@ -77,7 +77,7 @@
   if (c.bad == null) return;
   ({for (var x in c.bad) null: null});
   //              ^^^^^
-  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                ^
   // [cfe 14] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
 }
@@ -86,7 +86,7 @@
   if (c.bad == null) return;
   ({for (var x in c.bad) ...list});
   //              ^^^^^
-  // [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                ^
   // [cfe 15] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
 }
diff --git a/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart b/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
index 67f6c40..e2b3283 100644
--- a/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
+++ b/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
@@ -10,8 +10,8 @@
 class C1 {
   List<int>? bad;
   //         ^^^
-  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 2] 'bad' refers to a property so it couldn't be promoted.
+  // [context 1] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 2] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 test(C1 c) sync* {
diff --git a/tests/language/why_not_promoted/nullable_expression_call_error_test.dart b/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
index 46413a9..652702f 100644
--- a/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
+++ b/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
@@ -9,8 +9,8 @@
 class C1 {
   C2? bad;
   //  ^^^
-  // [context 3] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 7] 'bad' refers to a property so it couldn't be promoted.
+  // [context 1] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 7] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 class C2 {
@@ -21,7 +21,7 @@
   if (c.bad == null) return;
   c.bad();
 //^^^^^
-// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //     ^
 // [cfe 7] Can't use an expression of type 'C2?' as a function because it's potentially null.
 }
@@ -30,8 +30,8 @@
   C4? ok;
   C5? bad;
   //  ^^^
-  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 8] 'bad' refers to a property so it couldn't be promoted.
+  // [context 2] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 8] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 class C4 {}
@@ -52,7 +52,7 @@
   if (c.bad == null) return;
   c.bad();
 //^^^^^
-// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //     ^
 // [cfe 8] Can't use an expression of type 'C5?' as a function because it's potentially null.
 }
@@ -60,8 +60,8 @@
 class C6 {
   C7? bad;
   //  ^^^
-  // [context 6] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 9] 'bad' refers to a property so it couldn't be promoted.
+  // [context 3] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 9] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 class C7 {
@@ -73,7 +73,7 @@
   c.bad();
 //^^^^^
 // [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
-// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 //     ^
 // [cfe 9] Can't use an expression of type 'C7?' as a function because it's potentially null.
 }
@@ -81,8 +81,8 @@
 class C8 {
   C10? bad;
   //   ^^^
-  // [context 4] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 10] 'bad' refers to a property so it couldn't be promoted.
+  // [context 4] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 10] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 class C10 {}
@@ -103,8 +103,8 @@
 class C11 {
   void Function()? bad;
   //               ^^^
-  // [context 5] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 11] 'bad' refers to a property so it couldn't be promoted.
+  // [context 5] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 11] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 function_invocation(C11 c) {
@@ -119,8 +119,8 @@
 class C12 {
   C13? bad;
   //   ^^^
-  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 12] 'bad' refers to a property so it couldn't be promoted.
+  // [context 6] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 12] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 class C13 {
@@ -134,6 +134,6 @@
   // https://github.com/dart-lang/sdk/issues/45552
   c.bad.foo();
 //      ^^^
-// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 12] Can't use an expression of type 'C13?' as a function because it's potentially null.
 }
diff --git a/tests/language/why_not_promoted/nullable_method_call_error_test.dart b/tests/language/why_not_promoted/nullable_method_call_error_test.dart
index 56d5e93..d2a4f9e 100644
--- a/tests/language/why_not_promoted/nullable_method_call_error_test.dart
+++ b/tests/language/why_not_promoted/nullable_method_call_error_test.dart
@@ -9,18 +9,18 @@
 class C {
   int? i;
   //   ^
-  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 10] 'i' refers to a property so it couldn't be promoted.
-  // [context 11] 'i' refers to a property so it couldn't be promoted.
-  // [context 12] 'i' refers to a property so it couldn't be promoted.
-  // [context 13] 'i' refers to a property so it couldn't be promoted.
+  // [context 3] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 4] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 5] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 6] 'i' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 10] 'i' refers to a public field so it couldn't be promoted.
+  // [context 11] 'i' refers to a public field so it couldn't be promoted.
+  // [context 12] 'i' refers to a public field so it couldn't be promoted.
+  // [context 13] 'i' refers to a public field so it couldn't be promoted.
   void Function()? f;
   //               ^
-  // [context 7] 'f' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 14] 'f' refers to a property so it couldn't be promoted.
+  // [context 7] 'f' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 14] 'f' refers to a public field so it couldn't be promoted.
 }
 
 extension on int {
@@ -37,11 +37,11 @@
   if (i == null) return;
   i = j;
 //^^^^^
-// [context 6] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 1] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
 // [context 8] Variable 'i' could not be promoted due to an assignment.
   i.isEven;
 //  ^^^^^^
-// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
 }
 
@@ -49,12 +49,12 @@
   if (i == null) return;
   i = j;
 //^^^^^
-// [context 1] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
+// [context 2] Variable 'i' could not be promoted due to an assignment.  See http://dart.dev/go/non-promo-write
 // [context 9] Variable 'i' could not be promoted due to an assignment.
   i.propertyOnNullableInt;
   i.propertyOnNonNullInt;
 //  ^^^^^^^^^^^^^^^^^^^^
-// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 9] Property 'propertyOnNonNullInt' cannot be accessed on 'int?' because it is potentially null.
 }
 
@@ -71,7 +71,7 @@
   c.i.propertyOnNullableInt;
   c.i.propertyOnNonNullInt;
 //    ^^^^^^^^^^^^^^^^^^^^
-// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 11] Property 'propertyOnNonNullInt' cannot be accessed on 'int?' because it is potentially null.
 }
 
@@ -79,7 +79,7 @@
   if (c.i == null) return;
   c.i.abs();
 //    ^^^
-// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 12] Method 'abs' cannot be called on 'int?' because it is potentially null.
 }
 
@@ -88,7 +88,7 @@
   c.i.methodOnNullableInt();
   c.i.methodOnNonNullInt();
 //    ^^^^^^^^^^^^^^^^^^
-// [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 13] Method 'methodOnNonNullInt' cannot be called on 'int?' because it is potentially null.
 }
 
diff --git a/tests/language/why_not_promoted/nullable_operator_call_error_test.dart b/tests/language/why_not_promoted/nullable_operator_call_error_test.dart
index a145f34..a6c28f7 100644
--- a/tests/language/why_not_promoted/nullable_operator_call_error_test.dart
+++ b/tests/language/why_not_promoted/nullable_operator_call_error_test.dart
@@ -9,29 +9,29 @@
 class C1 {
   int? bad;
   //   ^^^
-  // [context 2] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'bad' refers to a property so it couldn't be promoted.
+  // [context 1] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 3] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 userDefinableBinaryOpLhs(C1 c) {
   if (c.bad == null) return;
   c.bad + 1;
   //    ^
-  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   // [cfe 3] Operator '+' cannot be called on 'int?' because it is potentially null.
 }
 
 class C2 {
   int? bad;
   //   ^^^
-  // [context 1] 'bad' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 4] 'bad' refers to a property so it couldn't be promoted.
+  // [context 2] 'bad' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 4] 'bad' refers to a public field so it couldn't be promoted.
 }
 
 userDefinableUnaryOp(C2 c) {
   if (c.bad == null) return;
   -c.bad;
 //^
-// [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 4] Operator 'unary-' cannot be called on 'int?' because it is potentially null.
 }
diff --git a/tests/language/why_not_promoted/nullable_spread_error_test.dart b/tests/language/why_not_promoted/nullable_spread_error_test.dart
index 03d98ed..aca987b 100644
--- a/tests/language/why_not_promoted/nullable_spread_error_test.dart
+++ b/tests/language/why_not_promoted/nullable_spread_error_test.dart
@@ -9,51 +9,51 @@
 class C {
   List<int>? listQuestion;
   //         ^^^^^^^^^^^^
-  // [context 7] 'listQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 9] 'listQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 15] 'listQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 17] 'listQuestion' refers to a property so it couldn't be promoted.
-  // [context 21] 'listQuestion' refers to a property so it couldn't be promoted.
-  // [context 27] 'listQuestion' refers to a property so it couldn't be promoted.
+  // [context 1] 'listQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 5] 'listQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 11] 'listQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 17] 'listQuestion' refers to a public field so it couldn't be promoted.
+  // [context 21] 'listQuestion' refers to a public field so it couldn't be promoted.
+  // [context 27] 'listQuestion' refers to a public field so it couldn't be promoted.
   Object? objectQuestion;
   //      ^^^^^^^^^^^^^^
-  // [context 1] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 6] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 10] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 11] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 12] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 16] 'objectQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 20] 'objectQuestion' refers to a property so it couldn't be promoted.
-  // [context 24] 'objectQuestion' refers to a property so it couldn't be promoted.
-  // [context 25] 'objectQuestion' refers to a property so it couldn't be promoted.
-  // [context 26] 'objectQuestion' refers to a property so it couldn't be promoted.
-  // [context 30] 'objectQuestion' refers to a property so it couldn't be promoted.
-  // [context 31] 'objectQuestion' refers to a property so it couldn't be promoted.
+  // [context 4] 'objectQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 8] 'objectQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 9] 'objectQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 10] 'objectQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 14] 'objectQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 15] 'objectQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 20] 'objectQuestion' refers to a public field so it couldn't be promoted.
+  // [context 24] 'objectQuestion' refers to a public field so it couldn't be promoted.
+  // [context 25] 'objectQuestion' refers to a public field so it couldn't be promoted.
+  // [context 26] 'objectQuestion' refers to a public field so it couldn't be promoted.
+  // [context 30] 'objectQuestion' refers to a public field so it couldn't be promoted.
+  // [context 31] 'objectQuestion' refers to a public field so it couldn't be promoted.
   Set<int>? setQuestion;
   //        ^^^^^^^^^^^
-  // [context 4] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 5] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 8] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 14] 'setQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 18] 'setQuestion' refers to a property so it couldn't be promoted.
-  // [context 22] 'setQuestion' refers to a property so it couldn't be promoted.
-  // [context 28] 'setQuestion' refers to a property so it couldn't be promoted.
-  // [context 32] 'setQuestion' refers to a property so it couldn't be promoted.
+  // [context 2] 'setQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 6] 'setQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 12] 'setQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 16] 'setQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 18] 'setQuestion' refers to a public field so it couldn't be promoted.
+  // [context 22] 'setQuestion' refers to a public field so it couldn't be promoted.
+  // [context 28] 'setQuestion' refers to a public field so it couldn't be promoted.
+  // [context 32] 'setQuestion' refers to a public field so it couldn't be promoted.
   Map<int, int>? mapQuestion;
   //             ^^^^^^^^^^^
-  // [context 2] 'mapQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'mapQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 13] 'mapQuestion' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 19] 'mapQuestion' refers to a property so it couldn't be promoted.
-  // [context 23] 'mapQuestion' refers to a property so it couldn't be promoted.
-  // [context 29] 'mapQuestion' refers to a property so it couldn't be promoted.
+  // [context 3] 'mapQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 7] 'mapQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 13] 'mapQuestion' refers to a public field so it couldn't be promoted.  See http://dart.dev/go/non-promo-public-field
+  // [context 19] 'mapQuestion' refers to a public field so it couldn't be promoted.
+  // [context 23] 'mapQuestion' refers to a public field so it couldn't be promoted.
+  // [context 29] 'mapQuestion' refers to a public field so it couldn't be promoted.
 }
 
 list_from_list_question(C c) {
   if (c.listQuestion == null) return;
   return [...c.listQuestion];
   //         ^^^^^^^^^^^^^^
-  // [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 17] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -62,7 +62,7 @@
   if (c.setQuestion == null) return;
   return [...c.setQuestion];
   //         ^^^^^^^^^^^^^
-  // [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 18] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -83,7 +83,7 @@
   return [...c.objectQuestion];
   //         ^^^^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
-  // [analyzer 16] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 20] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   // [cfe] Unexpected type 'Object?' of a spread.  Expected 'dynamic' or an Iterable.
@@ -93,7 +93,7 @@
   if (c.listQuestion == null) return;
   return {...c.listQuestion};
   //         ^^^^^^^^^^^^^^
-  // [analyzer 9] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 21] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -102,7 +102,7 @@
   if (c.setQuestion == null) return;
   return {...c.setQuestion};
   //         ^^^^^^^^^^^^^
-  // [analyzer 5] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 22] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -111,7 +111,7 @@
   if (c.mapQuestion == null) return;
   return {...c.mapQuestion};
   //         ^^^^^^^^^^^^^
-  // [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 7] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 23] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -122,7 +122,7 @@
   //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
   //               ^^^^^^^^^^^^^^^^
-  // [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 8] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                 ^
   // [cfe 24] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   // [cfe] Unexpected type 'Object?' of a spread.  Expected 'dynamic' or an Iterable.
@@ -134,7 +134,7 @@
   //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
   //                     ^^^^^^^^^^^^^^^^
-  // [analyzer 12] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 9] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                       ^
   // [cfe 25] Unexpected type 'Object?' of a map spread entry.  Expected 'dynamic' or a Map.
 }
@@ -144,7 +144,7 @@
   return <int>{...c.objectQuestion};
   //              ^^^^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
-  // [analyzer 1] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 10] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                ^
   // [cfe 26] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   // [cfe] Unexpected type 'Object?' of a spread.  Expected 'dynamic' or an Iterable.
@@ -154,7 +154,7 @@
   if (c.listQuestion == null) return;
   return {...c.listQuestion};
   //         ^^^^^^^^^^^^^^
-  // [analyzer 15] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 11] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 27] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -163,7 +163,7 @@
   if (c.setQuestion == null) return;
   return {...c.setQuestion};
   //         ^^^^^^^^^^^^^
-  // [analyzer 14] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 12] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //           ^
   // [cfe 28] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
 }
@@ -183,7 +183,7 @@
   //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
   //                     ^^^^^^^^^^^^^^^^
-  // [analyzer 10] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 14] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                       ^
   // [cfe 30] Unexpected type 'Object?' of a map spread entry.  Expected 'dynamic' or a Map.
 }
@@ -194,7 +194,7 @@
   //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
   //                          ^^^^^^^^^^^^^^^^
-  // [analyzer 11] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 15] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                            ^
   // [cfe 31] Unexpected type 'Object?' of a map spread entry.  Expected 'dynamic' or a Map.
 }
@@ -208,7 +208,7 @@
   return <int, int>{...c.setQuestion};
   //                   ^^^^^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.NOT_MAP_SPREAD
-  // [analyzer 8] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+  // [analyzer 16] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
   //                     ^
   // [cfe 32] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
   // [cfe] Unexpected type 'Set<int>?' of a map spread entry.  Expected 'dynamic' or a Map.
diff --git a/tests/language/why_not_promoted/property_error_test.dart b/tests/language/why_not_promoted/property_error_test.dart
index 02b1615..8e337e6 100644
--- a/tests/language/why_not_promoted/property_error_test.dart
+++ b/tests/language/why_not_promoted/property_error_test.dart
@@ -5,18 +5,18 @@
 class C {
   int? get i => null;
   //       ^
-  // [context 1] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 2] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 3] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 4] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 5] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 6] 'i' refers to a property so it couldn't be promoted.  See http://dart.dev/go/non-promo-property
-  // [context 7] 'i' refers to a property so it couldn't be promoted.
-  // [context 8] 'i' refers to a property so it couldn't be promoted.
-  // [context 9] 'i' refers to a property so it couldn't be promoted.
-  // [context 10] 'i' refers to a property so it couldn't be promoted.
-  // [context 11] 'i' refers to a property so it couldn't be promoted.
-  // [context 12] 'i' refers to a property so it couldn't be promoted.
+  // [context 1] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 2] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 3] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 4] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 5] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 6] 'i' refers to a getter so it couldn't be promoted.  See http://dart.dev/go/non-promo-non-field
+  // [context 7] 'i' refers to a getter so it couldn't be promoted.
+  // [context 8] 'i' refers to a getter so it couldn't be promoted.
+  // [context 9] 'i' refers to a getter so it couldn't be promoted.
+  // [context 10] 'i' refers to a getter so it couldn't be promoted.
+  // [context 11] 'i' refers to a getter so it couldn't be promoted.
+  // [context 12] 'i' refers to a getter so it couldn't be promoted.
   int? get j => null;
 
   get_property_via_explicit_this() {
@@ -31,7 +31,7 @@
     if ((this).i == null) return;
     (this).i.isEven;
 //           ^^^^^^
-// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 
@@ -39,7 +39,7 @@
     if (i == null) return;
     i.isEven;
 //    ^^^^^^
-// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 3] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 }
@@ -49,7 +49,7 @@
     if (super.i == null) return;
     super.i.isEven;
 //          ^^^^^^
-// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 4] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 10] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
   }
 
@@ -66,7 +66,7 @@
   if (c.i == null) return;
   c.i.isEven;
 //    ^^^^^^
-// [analyzer 2] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [analyzer 6] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
 // [cfe 12] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
 }
 
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index 8dc4c3c..c073aa6 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -37,7 +37,7 @@
       String request, String expectedMethod, String expectedUri,
       {int expectedTransferLength = 0,
       int expectedBytesReceived = 0,
-      Map<String, String>? expectedHeaders = null,
+      Map<String, String?>? expectedHeaders = null,
       bool chunked = false,
       bool upgrade = false,
       int unparsedLength = 0,
@@ -71,8 +71,8 @@
           Expect.equals(-1, incoming.transferLength);
         }
         if (expectedHeaders != null) {
-          expectedHeaders.forEach((String name, String value) =>
-              Expect.equals(value, headers![name]![0]));
+          expectedHeaders.forEach((String name, String? value) =>
+              Expect.equals(value, headers?[name]?[0]));
         }
         incoming.listen((List<int> data) {
           Expect.isFalse(upgraded);
@@ -539,6 +539,45 @@
     _testParseRequest(request, "POST", "/test",
         expectedTransferLength: -1, expectedBytesReceived: 60, chunked: true);
 
+    // Content-Length and "Transfer-Encoding: chunked" are specified.
+    request = """
+POST /test HTTP/1.1\r
+Content-Length: 10\r
+Transfer-Encoding: chunked\r
+\r
+5\r
+01234\r
+5\r
+56789\r
+0\r\n\r\n""";
+    _testParseRequest(request, "POST", "/test",
+        expectedTransferLength: -1,
+        expectedBytesReceived: 10,
+        chunked: true,
+        expectedHeaders: {
+          'content-length': null,
+          'transfer-encoding': 'chunked'
+        });
+
+    request = """
+POST /test HTTP/1.1\r
+Transfer-Encoding: chunked\r
+Content-Length: 10\r
+\r
+5\r
+01234\r
+5\r
+56789\r
+0\r\n\r\n""";
+    _testParseRequest(request, "POST", "/test",
+        expectedTransferLength: -1,
+        expectedBytesReceived: 10,
+        chunked: true,
+        expectedHeaders: {
+          'content-length': null,
+          'transfer-encoding': 'chunked'
+        });
+
     // Test HTTP upgrade.
     request = """
 GET /irc HTTP/1.1\r
@@ -798,32 +837,6 @@
 
     request = "GET / HTTP/1.1\r\nKeep-Alive: False\r\nbadheader\r\n\r\n";
     _testParseInvalidRequest(request);
-
-    // Content-Length and "Transfer-Encoding: chunked" are specified (error
-    // per RFC-7320).
-    request = """
-POST /test HTTP/1.1\r
-Content-Length: 7\r
-Transfer-Encoding: chunked\r
-\r
-5\r
-01234\r
-5\r
-56789\r
-0\r\n\r\n""";
-    _testParseInvalidRequest(request);
-
-    request = """
-POST /test HTTP/1.1\r
-Transfer-Encoding: chunked\r
-Content-Length: 7\r
-\r
-5\r
-01234\r
-5\r
-56789\r
-0\r\n\r\n""";
-    _testParseInvalidRequest(request);
   }
 
   void testParseInvalidResponse() {
diff --git a/tools/VERSION b/tools/VERSION
index d47c9a9..198f847 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 3
 MINOR 2
 PATCH 0
-PRERELEASE 206
+PRERELEASE 207
 PRERELEASE_PATCH 0