Version 2.18.0-172.0.dev

Merge commit '0d53291c30e66fca6b935df52f9c7bf5ac8803c0' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac2b73a..3791d3c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -56,11 +56,6 @@
 
 #### `dart:io`
 
-- **Breaking Change** [#34218](https://github.com/dart-lang/sdk/issues/34218):
-  Constants in `dart:io`'s networking APIs following the `SCREAMING_CAPS`
-  convention have been removed (they were previously deprecated). Please use
-  the corresponding `lowerCamelCase` constants instead.
-
 - **Breaking Change** [#45630][]: The Dart VM no longer automatically restores
     the initial terminal settings upon exit. Programs that change the `Stdin`
     settings `lineMode` and `echoMode` are now responsible for restoring the
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 2d52123..3b355eb 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -86,7 +86,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 222;
+  static const int DATA_VERSION = 223;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 0f4d313..9991ec3 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -43,6 +43,7 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/export.dart';
 import 'package:analyzer/src/summary2/macro.dart';
 import 'package:analyzer/src/summary2/macro_application_error.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -3713,7 +3714,7 @@
   @override
   late TypeSystemImpl typeSystem;
 
-  late final List<Reference> exportedReferences;
+  late final List<ExportedReference> exportedReferences;
 
   LibraryElementLinkedData? linkedData;
 
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 5b62894..9efb948 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/summary2/ast_binary_tag.dart';
 import 'package:analyzer/src/summary2/data_reader.dart';
 import 'package:analyzer/src/summary2/element_flags.dart';
+import 'package:analyzer/src/summary2/export.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/macro_application_error.dart';
@@ -462,10 +463,9 @@
       units.add(unitElement);
     }
 
-    var exportsIndexList = _reader.readUInt30List();
-    libraryElement.exportedReferences = exportsIndexList
-        .map((index) => _referenceReader.referenceOfIndex(index))
-        .toList();
+    libraryElement.exportedReferences = _reader.readTypedList(
+      _readExportedReference,
+    );
 
     libraryElement.definingCompilationUnit = units[0];
     libraryElement.parts = units.skip(1).toList();
@@ -627,6 +627,26 @@
     });
   }
 
+  ExportedReference _readExportedReference() {
+    final kind = _reader.readByte();
+    if (kind == 0) {
+      final index = _reader.readUInt30();
+      final reference = _referenceReader.referenceOfIndex(index);
+      return ExportedReferenceDeclared(
+        reference: reference,
+      );
+    } else if (kind == 1) {
+      final index = _reader.readUInt30();
+      final reference = _referenceReader.referenceOfIndex(index);
+      return ExportedReferenceExported(
+        reference: reference,
+        indexes: _reader.readUInt30List(),
+      );
+    } else {
+      throw StateError('kind: $kind');
+    }
+  }
+
   ExportElementImpl _readExportElement() {
     var element = ExportElementImpl(-1);
     element.uri = _reader.readOptionalStringReference();
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 4b3e6c3..ffd3fd6 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -18,6 +18,7 @@
 import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/data_writer.dart';
 import 'package:analyzer/src/summary2/element_flags.dart';
+import 'package:analyzer/src/summary2/export.dart';
 import 'package:analyzer/src/summary2/macro_application_error.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/inference_error.dart';
@@ -109,7 +110,7 @@
     for (var unitElement in libraryElement.units) {
       _writeUnitElement(unitElement);
     }
-    _writeReferences(libraryElement.exportedReferences);
+    _writeExportedReferences(libraryElement.exportedReferences);
 
     _libraries.add(
       _Library(
@@ -199,6 +200,22 @@
     });
   }
 
+  void _writeExportedReferences(List<ExportedReference> elements) {
+    _writeList<ExportedReference>(elements, (exported) {
+      final index = _references._indexOfReference(exported.reference);
+      if (exported is ExportedReferenceDeclared) {
+        _sink.writeByte(0);
+        _sink.writeUInt30(index);
+      } else if (exported is ExportedReferenceExported) {
+        _sink.writeByte(1);
+        _sink.writeUInt30(index);
+        _sink.writeUint30List(exported.indexes);
+      } else {
+        throw UnimplementedError('(${exported.runtimeType}) $exported');
+      }
+    });
+  }
+
   void _writeExportElement(ExportElement element) {
     _sink._writeOptionalStringReference(element.uri);
     _sink.writeList(element.combinators, _writeNamespaceCombinator);
@@ -385,16 +402,6 @@
     _writeList(element.parameters, _writeParameterElement);
   }
 
-  void _writeReferences(List<Reference> references) {
-    var length = references.length;
-    _sink.writeUInt30(length);
-
-    for (var reference in references) {
-      var index = _references._indexOfReference(reference);
-      _sink.writeUInt30(index);
-    }
-  }
-
   void _writeTopLevelVariableElement(TopLevelVariableElement element) {
     element as TopLevelVariableElementImpl;
     _sink.writeUInt30(_resolutionSink.offset);
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 47f889e..941f4e6 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -108,7 +108,7 @@
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addClass(name, element);
-    _libraryBuilder.localScope.declare(name, reference);
+    _libraryBuilder.declare(name, reference);
 
     var holder = _EnclosingContext(reference, element);
     _withEnclosing(holder, () {
@@ -142,7 +142,7 @@
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addClass(name, element);
-    _libraryBuilder.localScope.declare(name, reference);
+    _libraryBuilder.declare(name, reference);
 
     var holder = _EnclosingContext(reference, element);
     _withEnclosing(holder, () {
@@ -215,7 +215,7 @@
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addEnum(name, element);
-    _libraryBuilder.localScope.declare(name, reference);
+    _libraryBuilder.declare(name, reference);
 
     var holder = _EnclosingContext(
       reference,
@@ -414,7 +414,7 @@
     var reference = _enclosingContext.addExtension(refName, element);
 
     if (name != null) {
-      _libraryBuilder.localScope.declare(name, reference);
+      _libraryBuilder.declare(name, reference);
     }
 
     var holder = _EnclosingContext(reference, element);
@@ -595,11 +595,10 @@
       typeParameters: functionExpression.typeParameters,
     );
 
-    var localScope = _libraryBuilder.localScope;
     if (node.isSetter) {
-      localScope.declare('$name=', reference);
+      _libraryBuilder.declare('$name=', reference);
     } else {
-      localScope.declare(name, reference);
+      _libraryBuilder.declare(name, reference);
     }
 
     _buildType(node.returnType);
@@ -620,7 +619,7 @@
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addTypeAlias(name, element);
-    _libraryBuilder.localScope.declare(name, reference);
+    _libraryBuilder.declare(name, reference);
 
     var holder = _EnclosingContext(reference, element);
     _withEnclosing(holder, () {
@@ -728,7 +727,7 @@
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addTypeAlias(name, element);
-    _libraryBuilder.localScope.declare(name, reference);
+    _libraryBuilder.declare(name, reference);
 
     var holder = _EnclosingContext(reference, element);
     _withEnclosing(holder, () {
@@ -881,7 +880,7 @@
     _linker.elementNodes[element] = node;
 
     var reference = _enclosingContext.addMixin(name, element);
-    _libraryBuilder.localScope.declare(name, reference);
+    _libraryBuilder.declare(name, reference);
 
     var holder = _EnclosingContext(reference, element);
     _withEnclosing(holder, () {
@@ -1058,15 +1057,13 @@
       var getter = element.getter;
       if (getter is PropertyAccessorElementImpl) {
         _enclosingContext.addGetter(name, getter);
-        var localScope = _libraryBuilder.localScope;
-        localScope.declare(name, getter.reference!);
+        _libraryBuilder.declare(name, getter.reference!);
       }
 
       var setter = element.setter;
       if (setter is PropertyAccessorElementImpl) {
         _enclosingContext.addSetter(name, setter);
-        var localScope = _libraryBuilder.localScope;
-        localScope.declare('$name=', setter.reference!);
+        _libraryBuilder.declare('$name=', setter.reference!);
       }
     }
 
diff --git a/pkg/analyzer/lib/src/summary2/export.dart b/pkg/analyzer/lib/src/summary2/export.dart
index 8e733d7..2c79392 100644
--- a/pkg/analyzer/lib/src/summary2/export.dart
+++ b/pkg/analyzer/lib/src/summary2/export.dart
@@ -8,15 +8,86 @@
 
 class Export {
   final LibraryBuilder exporter;
+  final int index;
   final List<Combinator> combinators;
 
-  Export(this.exporter, this.combinators);
+  Export(this.exporter, this.index, this.combinators);
 
-  bool addToExportScope(String name, Reference reference) {
+  bool addToExportScope(String name, ExportedReference exported) {
     for (Combinator combinator in combinators) {
       if (combinator.isShow && !combinator.matches(name)) return false;
       if (combinator.isHide && combinator.matches(name)) return false;
     }
-    return exporter.addToExportScope(name, reference);
+    return exporter.exportScope.export(index, name, exported);
+  }
+}
+
+class ExportedReference {
+  final Reference reference;
+
+  ExportedReference({
+    required this.reference,
+  });
+
+  @override
+  String toString() {
+    return '$reference';
+  }
+}
+
+/// [ExportedReference] for a public element declared in the library.
+class ExportedReferenceDeclared extends ExportedReference {
+  ExportedReferenceDeclared({
+    required super.reference,
+  });
+}
+
+/// [ExportedReference] for an element that is re-exported.
+class ExportedReferenceExported extends ExportedReference {
+  /// The indexes of `export` directives (at least one) that export the element.
+  final List<int> indexes;
+
+  ExportedReferenceExported({
+    required super.reference,
+    required this.indexes,
+  });
+
+  void addExportIndex(int index) {
+    if (!indexes.contains(index)) {
+      indexes.add(index);
+    }
+  }
+}
+
+class ExportScope {
+  final Map<String, ExportedReference> map = {};
+
+  void declare(String name, Reference reference) {
+    map[name] = ExportedReferenceDeclared(
+      reference: reference,
+    );
+  }
+
+  bool export(int index, String name, ExportedReference exported) {
+    final existing = map[name];
+    if (existing?.reference == exported.reference) {
+      if (existing is ExportedReferenceExported) {
+        existing.addExportIndex(index);
+      }
+      return false;
+    }
+
+    // Ambiguous declaration detected.
+    if (existing != null) return false;
+
+    map[name] = ExportedReferenceExported(
+      reference: exported.reference,
+      indexes: [index],
+    );
+    return true;
+  }
+
+  void forEach(void Function(String name, ExportedReference reference) f) {
+    map.forEach(f);
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index f3b1e50..281b0ec 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -22,7 +22,6 @@
 import 'package:analyzer/src/summary2/metadata_resolver.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/reference_resolver.dart';
-import 'package:analyzer/src/summary2/scope.dart';
 import 'package:analyzer/src/summary2/types_builder.dart';
 import 'package:analyzer/src/util/performance/operation_performance.dart';
 
@@ -48,10 +47,10 @@
   final List<ImplicitEnumNodes> implicitEnumNodes = [];
 
   /// Local declarations.
-  final Scope localScope = Scope();
+  final Map<String, Reference> _declaredReferences = {};
 
   /// The export scope of the library.
-  final Scope exportScope = Scope();
+  final ExportScope exportScope = ExportScope();
 
   /// The `export` directives that export this library.
   final List<Export> exports = [];
@@ -86,13 +85,16 @@
   }
 
   void addExporters() {
-    for (var element in element.exports) {
-      var exportedLibrary = element.exportedLibrary;
+    final exportElements = element.exports;
+    for (var i = 0; i < exportElements.length; i++) {
+      final exportElement = exportElements[i];
+
+      final exportedLibrary = exportElement.exportedLibrary;
       if (exportedLibrary is! LibraryElementImpl) {
         continue;
       }
 
-      var combinators = element.combinators.map((combinator) {
+      final combinators = exportElement.combinators.map((combinator) {
         if (combinator is ShowElementCombinator) {
           return Combinator.show(combinator.shownNames);
         } else if (combinator is HideElementCombinator) {
@@ -102,41 +104,27 @@
         }
       }).toList();
 
-      var exportedUri = exportedLibrary.source.uri;
-      var exportedBuilder = linker.builders[exportedUri];
+      final exportedUri = exportedLibrary.source.uri;
+      final exportedBuilder = linker.builders[exportedUri];
 
-      var export = Export(this, combinators);
+      final export = Export(this, i, combinators);
       if (exportedBuilder != null) {
         exportedBuilder.exports.add(export);
       } else {
         final exportedReferences = exportedLibrary.exportedReferences;
-        for (final reference in exportedReferences) {
+        for (final exported in exportedReferences) {
+          final reference = exported.reference;
           final name = reference.name;
           if (reference.isSetter) {
-            export.addToExportScope('$name=', reference);
+            export.addToExportScope('$name=', exported);
           } else {
-            export.addToExportScope(name, reference);
+            export.addToExportScope(name, exported);
           }
         }
       }
     }
   }
 
-  /// Return `true` if the export scope was modified.
-  bool addToExportScope(String name, Reference reference) {
-    if (name.startsWith('_')) return false;
-    if (reference.isPrefix) return false;
-
-    var existing = exportScope.map[name];
-    if (existing == reference) return false;
-
-    // Ambiguous declaration detected.
-    if (existing != null) return false;
-
-    exportScope.map[name] = reference;
-    return true;
-  }
-
   /// Build elements for declarations in the library units, add top-level
   /// declarations to the local scope, for combining into export scopes.
   void buildElements() {
@@ -171,8 +159,10 @@
   }
 
   void buildInitialExportScope() {
-    localScope.forEach((name, reference) {
-      addToExportScope(name, reference);
+    _declaredReferences.forEach((name, reference) {
+      if (name.startsWith('_')) return;
+      if (reference.isPrefix) return;
+      exportScope.declare(name, reference);
     });
   }
 
@@ -194,6 +184,10 @@
     }
   }
 
+  void declare(String name, Reference reference) {
+    _declaredReferences[name] = reference;
+  }
+
   Future<void> executeMacroDeclarationsPhase() async {
     final macroApplier = _macroApplier;
     if (macroApplier == null) {
@@ -379,7 +373,8 @@
 
     var definedNames = <String, Element>{};
     for (var entry in exportScope.map.entries) {
-      var element = linker.elementFactory.elementOfReference(entry.value);
+      var reference = entry.value.reference;
+      var element = linker.elementFactory.elementOfReference(reference);
       if (element != null) {
         definedNames[entry.key] = element;
       }
@@ -399,11 +394,11 @@
     if (reference.name == 'dart:core') {
       var dynamicRef = reference.getChild('dynamic');
       dynamicRef.element = DynamicElementImpl.instance;
-      localScope.declare('dynamic', dynamicRef);
+      declare('dynamic', dynamicRef);
 
       var neverRef = reference.getChild('Never');
       neverRef.element = NeverElementImpl.instance;
-      localScope.declare('Never', neverRef);
+      declare('Never', neverRef);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index f329fbd..33ca9f8 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/export.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:meta/meta.dart';
 
@@ -68,11 +69,14 @@
     _libraryReaders.addAll(libraries);
   }
 
-  Namespace buildExportNamespace(Uri uri, List<Reference> exportedReferences) {
+  Namespace buildExportNamespace(
+    Uri uri,
+    List<ExportedReference> exportedReferences,
+  ) {
     var exportedNames = <String, Element>{};
 
     for (var exportedReference in exportedReferences) {
-      var element = elementOfReference(exportedReference);
+      var element = elementOfReference(exportedReference.reference);
       // TODO(scheglov) Remove after https://github.com/dart-lang/sdk/issues/41212
       if (element == null) {
         throw StateError(
diff --git a/pkg/analyzer/lib/src/summary2/scope.dart b/pkg/analyzer/lib/src/summary2/scope.dart
deleted file mode 100644
index ee59adc..0000000
--- a/pkg/analyzer/lib/src/summary2/scope.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/summary2/reference.dart';
-
-class Scope {
-  final Map<String, Reference> map = {};
-
-  void declare(String name, Reference reference) {
-    map[name] = reference;
-  }
-
-  void forEach(void Function(String name, Reference reference) f) {
-    map.forEach(f);
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 7400c6d..0befcb4 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -9,7 +9,9 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary2/export.dart';
 import 'package:analyzer/src/task/inference_error.dart';
+import 'package:collection/collection.dart';
 import 'package:test/test.dart';
 
 import 'resolved_ast_printer.dart';
@@ -135,6 +137,8 @@
   });
 
   void writeLibraryElement(LibraryElement e) {
+    e as LibraryElementImpl;
+
     _writelnWithIndent('library');
     _withIndent(() {
       var name = e.name;
@@ -169,9 +173,13 @@
       });
 
       if (withExportScope) {
-        _writelnWithIndent('exportScope');
+        _writelnWithIndent('exportedReferences');
         _withIndent(() {
-          _writeExportScope(e);
+          _writeExportedReferences(e);
+        });
+        _writelnWithIndent('exportNamespace');
+        _withIndent(() {
+          _writeExportNamespace(e);
         });
       }
     });
@@ -455,6 +463,23 @@
     }
   }
 
+  void _writeExportedReferences(LibraryElementImpl e) {
+    final exportedReferences = e.exportedReferences.toList();
+    exportedReferences.sortBy((e) => e.reference.toString());
+
+    for (final exported in exportedReferences) {
+      _writeIndentedLine(() {
+        if (exported is ExportedReferenceDeclared) {
+          buffer.write('declared ');
+        } else if (exported is ExportedReferenceExported) {
+          buffer.write('exported${exported.indexes} ');
+        }
+        // TODO(scheglov) Use the same writer as for resolved AST.
+        buffer.write(exported.reference);
+      });
+    }
+  }
+
   void _writeExportElement(ExportElement e) {
     _writeIndentedLine(() {
       _writeUri(e.exportedLibrary?.source);
@@ -468,7 +493,7 @@
     _assertNonSyntheticElementSelf(e);
   }
 
-  void _writeExportScope(LibraryElement e) {
+  void _writeExportNamespace(LibraryElement e) {
     var map = e.exportNamespace.definedNames;
     var names = map.keys.toList()..sort();
     for (var name in names) {
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index 331a9ab..30a655d 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -19983,7 +19983,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::C
+  exportNamespace
     C: package:test/a.dart;C
 ''',
         withExportScope: true);
@@ -20003,7 +20005,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::C
+  exportNamespace
     C: package:test/a.dart;C
 ''',
         withExportScope: true);
@@ -20028,7 +20032,9 @@
   exports
     package:test/foo.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/foo.dart::@unit::package:test/foo.dart::@class::A
+  exportNamespace
     A: package:test/foo.dart;A
 ''',
         withExportScope: true);
@@ -20055,7 +20061,9 @@
   exports
     package:test/foo_io.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/foo_io.dart::@unit::package:test/foo_io.dart::@class::A
+  exportNamespace
     A: package:test/foo_io.dart;A
 ''',
         withExportScope: true);
@@ -20082,7 +20090,9 @@
   exports
     package:test/foo_html.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/foo_html.dart::@unit::package:test/foo_html.dart::@class::A
+  exportNamespace
     A: package:test/foo_html.dart;A
 ''',
         withExportScope: true);
@@ -20090,6 +20100,37 @@
     expect(export.exportedLibrary!.source.shortName, 'foo_html.dart');
   }
 
+  test_export_cycle() async {
+    addSource('$testPackageLibPath/a.dart', r'''
+export 'test.dart';
+class A {}
+''');
+
+    var library = await buildLibrary(r'''
+export 'a.dart';
+class X {}
+''');
+    checkElementText(
+        library,
+        r'''
+library
+  exports
+    package:test/a.dart
+  definingUnit
+    classes
+      class X @23
+        constructors
+          synthetic @-1
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::A
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::X
+  exportNamespace
+    A: package:test/a.dart;A
+    X: package:test/test.dart;X
+''',
+        withExportScope: true);
+  }
+
   test_export_function() async {
     addSource('$testPackageLibPath/a.dart', 'f() {}');
     var library = await buildLibrary('export "a.dart";');
@@ -20100,7 +20141,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@function::f
+  exportNamespace
     f: package:test/a.dart;f
 ''',
         withExportScope: true);
@@ -20136,7 +20179,10 @@
       combinators
         hide: A, C
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::B
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::D
+  exportNamespace
     B: package:test/a.dart;B
     D: package:test/a.dart;D
 ''',
@@ -20163,12 +20209,60 @@
         hide: A
         show: C
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::C
+  exportNamespace
     C: package:test/a.dart;C
 ''',
         withExportScope: true);
   }
 
+  test_export_reexport() async {
+    addSource('$testPackageLibPath/a.dart', r'''
+class A {}
+''');
+
+    addSource('$testPackageLibPath/b.dart', r'''
+export 'a.dart';
+class B {}
+''');
+
+    addSource('$testPackageLibPath/c.dart', r'''
+export 'a.dart';
+class C {}
+''');
+
+    var library = await buildLibrary(r'''
+export 'b.dart';
+export 'c.dart';
+class X {}
+''');
+    checkElementText(
+        library,
+        r'''
+library
+  exports
+    package:test/b.dart
+    package:test/c.dart
+  definingUnit
+    classes
+      class X @40
+        constructors
+          synthetic @-1
+  exportedReferences
+    exported[0, 1] root::package:test/a.dart::@unit::package:test/a.dart::@class::A
+    exported[0] root::package:test/b.dart::@unit::package:test/b.dart::@class::B
+    exported[1] root::package:test/c.dart::@unit::package:test/c.dart::@class::C
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::X
+  exportNamespace
+    A: package:test/a.dart;A
+    B: package:test/b.dart;B
+    C: package:test/c.dart;C
+    X: package:test/test.dart;X
+''',
+        withExportScope: true);
+  }
+
   test_export_setter() async {
     addSource('$testPackageLibPath/a.dart', 'void set f(value) {}');
     var library = await buildLibrary('export "a.dart";');
@@ -20179,7 +20273,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@setter::f
+  exportNamespace
     f=: package:test/a.dart;f=
 ''',
         withExportScope: true);
@@ -20204,7 +20300,10 @@
       combinators
         show: A, C
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::A
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@class::C
+  exportNamespace
     A: package:test/a.dart;A
     C: package:test/a.dart;C
 ''',
@@ -20226,7 +20325,10 @@
       combinators
         show: f
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@getter::f
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@setter::f
+  exportNamespace
     f: package:test/a.dart;f?
     f=: package:test/a.dart;f=
 ''',
@@ -20243,7 +20345,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@typeAlias::F
+  exportNamespace
     F: package:test/a.dart;F
 ''',
         withExportScope: true);
@@ -20266,7 +20370,10 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@getter::x
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@setter::x
+  exportNamespace
     x: package:test/a.dart;x?
     x=: package:test/a.dart;x=
 ''',
@@ -20283,7 +20390,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@getter::x
+  exportNamespace
     x: package:test/a.dart;x?
 ''',
         withExportScope: true);
@@ -20299,7 +20408,9 @@
   exports
     package:test/a.dart
   definingUnit
-  exportScope
+  exportedReferences
+    exported[0] root::package:test/a.dart::@unit::package:test/a.dart::@getter::x
+  exportNamespace
     x: package:test/a.dart;x?
 ''',
         withExportScope: true);
@@ -20415,7 +20526,8 @@
     package:test/a.dart
     package:test/b.dart
   definingUnit
-  exportScope
+  exportedReferences
+  exportNamespace
 ''',
         withExportScope: true);
   }
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index 0d65812..b6f1d61 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -138,7 +138,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -199,7 +202,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -268,7 +274,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -337,7 +346,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -399,7 +411,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -469,7 +484,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -538,7 +556,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
@@ -612,7 +633,10 @@
         class MyClass @-1
           constructors
             synthetic @-1
-  exportScope
+  exportedReferences
+    declared root::package:test/test.dart::@unit::package:test/_macro_types.dart::@class::MyClass
+    declared root::package:test/test.dart::@unit::package:test/test.dart::@class::A
+  exportNamespace
     A: package:test/test.dart;A
     MyClass: package:test/test.dart;package:test/_macro_types.dart;MyClass
 ''',
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 320a50c..3bb84ee 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1446,8 +1446,19 @@
           templateNotConstantExpression
               .withArguments('Non-constant list literal'));
     }
+
+    DartType? type = _evaluateDartType(node, node.typeArgument);
+    if (type == null) {
+      AbortConstant error = _gotError!;
+      _gotError = null;
+      return error;
+    }
+    assert(_gotError == null);
+    // ignore: unnecessary_null_comparison
+    assert(type != null);
+
     final ListConstantBuilder builder = new ListConstantBuilder(
-        node, convertType(node.typeArgument), this,
+        node, convertType(type), this,
         isMutable: !node.isConst);
     // These expressions are at the same level, so one of them being
     // unevaluated doesn't mean a sibling is or has an unevaluated child.
@@ -1483,8 +1494,19 @@
           templateNotConstantExpression
               .withArguments('Non-constant set literal'));
     }
+
+    DartType? type = _evaluateDartType(node, node.typeArgument);
+    if (type == null) {
+      AbortConstant error = _gotError!;
+      _gotError = null;
+      return error;
+    }
+    assert(_gotError == null);
+    // ignore: unnecessary_null_comparison
+    assert(type != null);
+
     final SetConstantBuilder builder =
-        new SetConstantBuilder(node, convertType(node.typeArgument), this);
+        new SetConstantBuilder(node, convertType(type), this);
     // These expressions are at the same level, so one of them being
     // unevaluated doesn't mean a sibling is or has an unevaluated child.
     // We therefore reset it before each call, combine it and set it correctly
@@ -1519,8 +1541,29 @@
           templateNotConstantExpression
               .withArguments('Non-constant map literal'));
     }
+
+    DartType? keyType = _evaluateDartType(node, node.keyType);
+    if (keyType == null) {
+      AbortConstant error = _gotError!;
+      _gotError = null;
+      return error;
+    }
+    assert(_gotError == null);
+    // ignore: unnecessary_null_comparison
+    assert(keyType != null);
+
+    DartType? valueType = _evaluateDartType(node, node.valueType);
+    if (valueType == null) {
+      AbortConstant error = _gotError!;
+      _gotError = null;
+      return error;
+    }
+    assert(_gotError == null);
+    // ignore: unnecessary_null_comparison
+    assert(valueType != null);
+
     final MapConstantBuilder builder = new MapConstantBuilder(
-        node, convertType(node.keyType), convertType(node.valueType), this);
+        node, convertType(keyType), convertType(valueType), this);
     // These expressions are at the same level, so one of them being
     // unevaluated doesn't mean a sibling is or has an unevaluated child.
     // We therefore reset it before each call, combine it and set it correctly
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 60370ac..4549c6b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -69,7 +69,7 @@
     int fileOffset;
     if (!inferrer.isTopLevel) {
       // In local inference we have access to the current file uri.
-      uri = inferrer.helper!.uri;
+      uri = inferrer.helper.uri;
       fileOffset = node.fileOffset;
     } else {
       Location? location = node.location;
@@ -429,7 +429,7 @@
         }
         if (operandType.isPotentiallyNullable) {
           if (!inferrer.isTopLevel) {
-            result = inferrer.helper!.buildProblem(
+            result = inferrer.helper.buildProblem(
                 templateInstantiationNullableGenericFunctionType.withArguments(
                     operandType, inferrer.isNonNullableByDefault),
                 node.fileOffset,
@@ -443,14 +443,14 @@
       } else {
         if (!inferrer.isTopLevel) {
           if (operandType.typeParameters.isEmpty) {
-            result = inferrer.helper!.buildProblem(
+            result = inferrer.helper.buildProblem(
                 templateInstantiationNonGenericFunctionType.withArguments(
                     operandType, inferrer.isNonNullableByDefault),
                 node.fileOffset,
                 noLength);
           } else if (operandType.typeParameters.length >
               node.typeArguments.length) {
-            result = inferrer.helper!.buildProblem(
+            result = inferrer.helper.buildProblem(
                 templateInstantiationTooFewArguments.withArguments(
                     operandType.typeParameters.length,
                     node.typeArguments.length),
@@ -458,7 +458,7 @@
                 noLength);
           } else if (operandType.typeParameters.length <
               node.typeArguments.length) {
-            result = inferrer.helper!.buildProblem(
+            result = inferrer.helper.buildProblem(
                 templateInstantiationTooManyArguments.withArguments(
                     operandType.typeParameters.length,
                     node.typeArguments.length),
@@ -469,7 +469,7 @@
       }
     } else if (operandType is! InvalidType) {
       if (!inferrer.isTopLevel) {
-        result = inferrer.helper!.buildProblem(
+        result = inferrer.helper.buildProblem(
             templateInstantiationNonGenericFunctionType.withArguments(
                 operandType, inferrer.isNonNullableByDefault),
             node.fileOffset,
@@ -716,7 +716,7 @@
       SourceLibraryBuilder library = inferrer.libraryBuilder;
       if (!hadExplicitTypeArguments) {
         library.checkBoundsInConstructorInvocation(
-            node, inferrer.typeSchemaEnvironment, inferrer.helper!.uri,
+            node, inferrer.typeSchemaEnvironment, inferrer.helper.uri,
             inferred: true);
       }
     }
@@ -750,7 +750,7 @@
       inferrer.libraryBuilder.checkBoundsInStaticInvocation(
           replacement,
           inferrer.typeSchemaEnvironment,
-          inferrer.helper!.uri,
+          inferrer.helper.uri,
           typeArgumentsInfo);
     }
     return inferrer.instantiateTearOff(
@@ -1013,12 +1013,12 @@
       SourceLibraryBuilder library = inferrer.libraryBuilder;
       if (!hadExplicitTypeArguments) {
         library.checkBoundsInFactoryInvocation(
-            node, inferrer.typeSchemaEnvironment, inferrer.helper!.uri,
+            node, inferrer.typeSchemaEnvironment, inferrer.helper.uri,
             inferred: true);
       }
       if (inferrer.isNonNullableByDefault) {
         if (node.target == inferrer.coreTypes.listDefaultConstructor) {
-          resultNode = inferrer.helper!.wrapInProblem(node,
+          resultNode = inferrer.helper.wrapInProblem(node,
               messageDefaultListConstructorError, node.fileOffset, noLength);
         }
       }
@@ -1043,7 +1043,7 @@
     if (!inferrer.isTopLevel) {
       if (inferrer.isNonNullableByDefault) {
         if (node.target == inferrer.coreTypes.listDefaultConstructor) {
-          resultNode = inferrer.helper!.wrapInProblem(node,
+          resultNode = inferrer.helper.wrapInProblem(node,
               messageDefaultListConstructorError, node.fileOffset, noLength);
         }
       }
@@ -1068,7 +1068,7 @@
     if (!inferrer.isTopLevel) {
       if (inferrer.isNonNullableByDefault) {
         if (node.target == inferrer.coreTypes.listDefaultConstructor) {
-          resultNode = inferrer.helper!.wrapInProblem(node,
+          resultNode = inferrer.helper.wrapInProblem(node,
               messageDefaultListConstructorError, node.fileOffset, noLength);
         }
       }
@@ -1572,7 +1572,7 @@
 
     int? intValue = node.asInt64();
     if (intValue == null) {
-      Expression replacement = inferrer.helper!.buildProblem(
+      Expression replacement = inferrer.helper.buildProblem(
           templateIntegerLiteralIsOutOfRange.withArguments(node.literal),
           node.fileOffset,
           node.literal.length);
@@ -1699,7 +1699,7 @@
         if (spreadElementType == null) {
           if (inferrer.coreTypes.isNull(spreadTypeBound) &&
               !element.isNullAware) {
-            replacement = inferrer.helper!.buildProblem(
+            replacement = inferrer.helper.buildProblem(
                 templateNonNullAwareSpreadIsNull.withArguments(
                     spreadType, inferrer.isNonNullableByDefault),
                 element.expression.fileOffset,
@@ -1711,7 +1711,7 @@
                 spreadType is! NullType &&
                 !element.isNullAware) {
               Expression receiver = element.expression;
-              replacement = inferrer.helper!.buildProblem(
+              replacement = inferrer.helper.buildProblem(
                   messageNullableSpreadError, receiver.fileOffset, 1,
                   context: inferrer.getWhyNotPromotedContext(
                       inferrer.flowAnalysis.whyNotPromoted(receiver)(),
@@ -1719,7 +1719,7 @@
                       (type) => !type.isPotentiallyNullable));
             }
 
-            replacement = inferrer.helper!.buildProblem(
+            replacement = inferrer.helper.buildProblem(
                 templateSpreadTypeMismatch.withArguments(
                     spreadType, inferrer.isNonNullableByDefault),
                 element.expression.fileOffset,
@@ -1735,7 +1735,7 @@
               if (subtypeCheckResult.isSubtypeWhenIgnoringNullabilities()) {
                 if (spreadElementType == subtypeCheckResult.subtype &&
                     inferredTypeArgument == subtypeCheckResult.supertype) {
-                  replacement = inferrer.helper!.buildProblem(
+                  replacement = inferrer.helper.buildProblem(
                       templateSpreadElementTypeMismatchNullability
                           .withArguments(
                               spreadElementType,
@@ -1744,7 +1744,7 @@
                       element.expression.fileOffset,
                       1);
                 } else {
-                  replacement = inferrer.helper!.buildProblem(
+                  replacement = inferrer.helper.buildProblem(
                       templateSpreadElementTypeMismatchPartNullability
                           .withArguments(
                               spreadElementType,
@@ -1756,7 +1756,7 @@
                       1);
                 }
               } else {
-                replacement = inferrer.helper!.buildProblem(
+                replacement = inferrer.helper.buildProblem(
                     templateSpreadElementTypeMismatch.withArguments(
                         spreadElementType,
                         inferredTypeArgument,
@@ -1765,7 +1765,7 @@
                     1);
               }
             } else {
-              replacement = inferrer.helper!.buildProblem(
+              replacement = inferrer.helper.buildProblem(
                   templateSpreadElementTypeMismatch.withArguments(
                       spreadElementType,
                       inferredTypeArgument,
@@ -1780,7 +1780,7 @@
               spreadType is! NullType &&
               !element.isNullAware) {
             Expression receiver = element.expression;
-            replacement = inferrer.helper!.buildProblem(
+            replacement = inferrer.helper.buildProblem(
                 messageNullableSpreadError, receiver.fileOffset, 1,
                 context: inferrer.getWhyNotPromotedContext(
                     inferrer.flowAnalysis.whyNotPromoted(receiver)(),
@@ -2203,7 +2203,7 @@
           if (inferrer.coreTypes.isNull(spreadTypeBound) &&
               !entry.isNullAware) {
             replacement = new MapLiteralEntry(
-                inferrer.helper!.buildProblem(
+                inferrer.helper.buildProblem(
                     templateNonNullAwareSpreadIsNull.withArguments(
                         spreadType, inferrer.isNonNullableByDefault),
                     entry.expression.fileOffset,
@@ -2217,7 +2217,7 @@
                 spreadType is! NullType &&
                 !entry.isNullAware) {
               Expression receiver = entry.expression;
-              Expression problem = inferrer.helper!.buildProblem(
+              Expression problem = inferrer.helper.buildProblem(
                   messageNullableSpreadError, receiver.fileOffset, 1,
                   context: inferrer.getWhyNotPromotedContext(
                       inferrer.flowAnalysis.whyNotPromoted(receiver)(),
@@ -2233,7 +2233,7 @@
             iterableSpreadType = spreadType;
           } else {
             Expression receiver = entry.expression;
-            Expression problem = inferrer.helper!.buildProblem(
+            Expression problem = inferrer.helper.buildProblem(
                 templateSpreadMapEntryTypeMismatch.withArguments(
                     spreadType, inferrer.isNonNullableByDefault),
                 receiver.fileOffset,
@@ -2257,14 +2257,14 @@
               if (subtypeCheckResult.isSubtypeWhenIgnoringNullabilities()) {
                 if (actualKeyType == subtypeCheckResult.subtype &&
                     inferredKeyType == subtypeCheckResult.supertype) {
-                  keyError = inferrer.helper!.buildProblem(
+                  keyError = inferrer.helper.buildProblem(
                       templateSpreadMapEntryElementKeyTypeMismatchNullability
                           .withArguments(actualKeyType, inferredKeyType,
                               inferrer.isNonNullableByDefault),
                       entry.expression.fileOffset,
                       1);
                 } else {
-                  keyError = inferrer.helper!.buildProblem(
+                  keyError = inferrer.helper.buildProblem(
                       // ignore: lines_longer_than_80_chars
                       templateSpreadMapEntryElementKeyTypeMismatchPartNullability
                           .withArguments(
@@ -2277,7 +2277,7 @@
                       1);
                 }
               } else {
-                keyError = inferrer.helper!.buildProblem(
+                keyError = inferrer.helper.buildProblem(
                     templateSpreadMapEntryElementKeyTypeMismatch.withArguments(
                         actualKeyType,
                         inferredKeyType,
@@ -2286,7 +2286,7 @@
                     1);
               }
             } else {
-              keyError = inferrer.helper!.buildProblem(
+              keyError = inferrer.helper.buildProblem(
                   templateSpreadMapEntryElementKeyTypeMismatch.withArguments(
                       actualKeyType,
                       inferredKeyType,
@@ -2303,14 +2303,14 @@
               if (subtypeCheckResult.isSubtypeWhenIgnoringNullabilities()) {
                 if (actualValueType == subtypeCheckResult.subtype &&
                     inferredValueType == subtypeCheckResult.supertype) {
-                  valueError = inferrer.helper!.buildProblem(
+                  valueError = inferrer.helper.buildProblem(
                       templateSpreadMapEntryElementValueTypeMismatchNullability
                           .withArguments(actualValueType, inferredValueType,
                               inferrer.isNonNullableByDefault),
                       entry.expression.fileOffset,
                       1);
                 } else {
-                  valueError = inferrer.helper!.buildProblem(
+                  valueError = inferrer.helper.buildProblem(
                       // ignore: lines_longer_than_80_chars
                       templateSpreadMapEntryElementValueTypeMismatchPartNullability
                           .withArguments(
@@ -2323,7 +2323,7 @@
                       1);
                 }
               } else {
-                valueError = inferrer.helper!.buildProblem(
+                valueError = inferrer.helper.buildProblem(
                     templateSpreadMapEntryElementValueTypeMismatch
                         .withArguments(actualValueType, inferredValueType,
                             inferrer.isNonNullableByDefault),
@@ -2331,7 +2331,7 @@
                     1);
               }
             } else {
-              valueError = inferrer.helper!.buildProblem(
+              valueError = inferrer.helper.buildProblem(
                   templateSpreadMapEntryElementValueTypeMismatch.withArguments(
                       actualValueType,
                       inferredValueType,
@@ -2346,7 +2346,7 @@
               spreadType is! NullType &&
               !entry.isNullAware) {
             Expression receiver = entry.expression;
-            keyError = inferrer.helper!.buildProblem(
+            keyError = inferrer.helper.buildProblem(
                 messageNullableSpreadError, receiver.fileOffset, 1,
                 context: inferrer.getWhyNotPromotedContext(
                     inferrer.flowAnalysis.whyNotPromoted(receiver)(),
@@ -2618,7 +2618,7 @@
     MapLiteralEntry replacement = entry;
     if (iterableSpreadOffset != null) {
       replacement = new MapLiteralEntry(
-          inferrer.helper!.buildProblem(
+          inferrer.helper.buildProblem(
               templateSpreadMapEntryTypeMismatch.withArguments(
                   iterableSpreadType!, inferrer.isNonNullableByDefault),
               iterableSpreadOffset!,
@@ -2786,7 +2786,9 @@
         InterfaceType setType = inferrer.coreTypes.thisInterfaceType(
             inferrer.coreTypes.setClass, inferrer.libraryBuilder.nonNullable);
         for (int i = 0; i < node.entries.length; ++i) {
-          setElements.add(convertToElement(node.entries[i], inferrer.helper,
+          setElements.add(convertToElement(
+              node.entries[i],
+              inferrer.isTopLevel ? null : inferrer.helper,
               inferrer.assignedVariables.reassignInfo));
           formalTypesForSet.add(setType.typeArguments[0]);
         }
@@ -2838,7 +2840,7 @@
       if (canBeSet && canBeMap && node.entries.isNotEmpty) {
         Expression replacement = node;
         if (!inferrer.isTopLevel) {
-          replacement = inferrer.helper!.buildProblem(
+          replacement = inferrer.helper.buildProblem(
               messageCantDisambiguateNotEnoughInformation, node.fileOffset, 1);
         }
         return new ExpressionInferenceResult(
@@ -2848,7 +2850,7 @@
       if (!canBeSet && !canBeMap) {
         Expression replacement = node;
         if (!inferrer.isTopLevel) {
-          replacement = inferrer.helper!.buildProblem(
+          replacement = inferrer.helper.buildProblem(
               messageCantDisambiguateAmbiguousInformation, node.fileOffset, 1);
         }
         return new ExpressionInferenceResult(
@@ -4396,7 +4398,7 @@
           (type) => !type.isPotentiallyNullable);
       return new ExpressionInferenceResult(
           binaryType,
-          inferrer.helper!.wrapInProblem(
+          inferrer.helper.wrapInProblem(
               binary,
               templateNullableOperatorCallError.withArguments(
                   binaryName.text, leftType, inferrer.isNonNullableByDefault),
@@ -4516,7 +4518,7 @@
       // probably be referred to as "Unary operator '-' ...".
       return new ExpressionInferenceResult(
           unaryType,
-          inferrer.helper!.wrapInProblem(
+          inferrer.helper.wrapInProblem(
               unary,
               templateNullableOperatorCallError.withArguments(unaryName.text,
                   expressionType, inferrer.isNonNullableByDefault),
@@ -4652,7 +4654,7 @@
     if (!inferrer.isTopLevel && readTarget.isNullable) {
       return new ExpressionInferenceResult(
           readType,
-          inferrer.helper!.wrapInProblem(
+          inferrer.helper.wrapInProblem(
               read,
               templateNullableOperatorCallError.withArguments(indexGetName.text,
                   receiverType, inferrer.isNonNullableByDefault),
@@ -4751,7 +4753,7 @@
         break;
     }
     if (!inferrer.isTopLevel && writeTarget.isNullable) {
-      return inferrer.helper!.wrapInProblem(
+      return inferrer.helper.wrapInProblem(
           write,
           templateNullableOperatorCallError.withArguments(
               indexSetName.text, receiverType, inferrer.isNonNullableByDefault),
@@ -5037,7 +5039,7 @@
         break;
     }
     if (!inferrer.isTopLevel && writeTarget.isNullable) {
-      return inferrer.helper!.wrapInProblem(
+      return inferrer.helper.wrapInProblem(
           write,
           templateNullablePropertyAccessError.withArguments(
               propertyName.text, receiverType, inferrer.isNonNullableByDefault),
@@ -6039,7 +6041,7 @@
       }
 
       if (!library.loader.target.backendTarget.supportsSetLiterals) {
-        inferrer.helper!.transformSetLiterals = true;
+        inferrer.helper.transformSetLiterals = true;
       }
     }
     return new ExpressionInferenceResult(inferredType, node);
@@ -6099,7 +6101,7 @@
       inferrer.libraryBuilder.checkBoundsInStaticInvocation(
           node,
           inferrer.typeSchemaEnvironment,
-          inferrer.helper!.uri,
+          inferrer.helper.uri,
           typeArgumentsInfo);
     }
     return new ExpressionInferenceResult(
@@ -6310,7 +6312,7 @@
           if (inferrer.libraryBuilder.isNonNullableByDefault) {
             if (!inferrer.typeSchemaEnvironment.isSubtypeOf(caseExpressionType,
                 expressionType, SubtypeCheckMode.withNullabilities)) {
-              inferrer.helper!.addProblem(
+              inferrer.helper.addProblem(
                   templateSwitchExpressionNotSubtype.withArguments(
                       caseExpressionType,
                       expressionType,
@@ -6328,7 +6330,7 @@
             // Check whether the expression type is assignable to the case
             // expression type.
             if (!inferrer.isAssignable(expressionType, caseExpressionType)) {
-              inferrer.helper!.addProblem(
+              inferrer.helper.addProblem(
                   templateSwitchExpressionNotAssignable.withArguments(
                       expressionType,
                       caseExpressionType,
@@ -6358,7 +6360,7 @@
           if (caseIndex < node.cases.length - 1 &&
               inferrer.flowAnalysis.isReachable) {
             inferrer.libraryBuilder.addProblem(messageSwitchCaseFallThrough,
-                switchCase.fileOffset, noLength, inferrer.helper!.uri);
+                switchCase.fileOffset, noLength, inferrer.helper.uri);
           }
         }
       }
@@ -6431,7 +6433,7 @@
           expressionResult.inferredType)) {
         return new ExpressionInferenceResult(
             const DynamicType(),
-            inferrer.helper!.buildProblem(
+            inferrer.helper.buildProblem(
                 templateThrowingNotAssignableToObjectError.withArguments(
                     expressionResult.inferredType, true),
                 node.expression.fileOffset,
@@ -6563,7 +6565,7 @@
           if (isDefinitelyAssigned) {
             return new ExpressionInferenceResult(
                 resultType,
-                inferrer.helper!.wrapInProblem(
+                inferrer.helper.wrapInProblem(
                     resultExpression,
                     templateLateDefinitelyAssignedError
                         .withArguments(node.variable.name!),
@@ -6574,7 +6576,7 @@
           if (!isDefinitelyUnassigned) {
             return new ExpressionInferenceResult(
                 resultType,
-                inferrer.helper!.wrapInProblem(
+                inferrer.helper.wrapInProblem(
                     resultExpression,
                     templateFinalPossiblyAssignedError
                         .withArguments(node.variable.name!),
@@ -6857,7 +6859,7 @@
               String name = variable.lateName ?? variable.name!;
               return new ExpressionInferenceResult(
                   resultType,
-                  inferrer.helper!.wrapInProblem(
+                  inferrer.helper.wrapInProblem(
                       resultExpression,
                       templateLateDefinitelyUnassignedError.withArguments(name),
                       node.fileOffset,
@@ -6868,7 +6870,7 @@
               if (variable.isFinal) {
                 return new ExpressionInferenceResult(
                     resultType,
-                    inferrer.helper!.wrapInProblem(
+                    inferrer.helper.wrapInProblem(
                         resultExpression,
                         templateFinalNotAssignedError
                             .withArguments(node.variable.name!),
@@ -6877,7 +6879,7 @@
               } else if (declaredOrInferredType.isPotentiallyNonNullable) {
                 return new ExpressionInferenceResult(
                     resultType,
-                    inferrer.helper!.wrapInProblem(
+                    inferrer.helper.wrapInProblem(
                         resultExpression,
                         templateNonNullableNotAssignedError
                             .withArguments(node.variable.name!),
@@ -7039,7 +7041,7 @@
           }
           int? intValue = receiver.asInt64(negated: true);
           if (intValue == null) {
-            Expression error = inferrer.helper!.buildProblem(
+            Expression error = inferrer.helper.buildProblem(
                 templateIntegerLiteralIsOutOfRange
                     .withArguments(receiver.literal),
                 receiver.fileOffset,
@@ -7088,7 +7090,7 @@
                 operationName, operandType, inferrer.isNonNullableByDefault),
             offset,
             noLength,
-            inferrer.helper!.uri);
+            inferrer.helper.uri);
       }
     }
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 56d562f..1c0c5c4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1032,7 +1032,7 @@
       ? '0x${asDouble.toRadixString(16)}'
       : asDouble.toString();
   int length = literal?.length ?? noLength;
-  return inferrer.helper!.buildProblem(
+  return inferrer.helper.buildProblem(
       templateWebLiteralCannotBeRepresentedExactly.withArguments(text, nearest),
       charOffset,
       length);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart b/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
index 4d46072..c7f66b4 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
@@ -172,7 +172,7 @@
             returnType is NullType) {
           // Valid return;
         } else {
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               new NullLiteral()..fileOffset = statement.fileOffset,
               messageReturnWithoutExpressionSync,
               statement.fileOffset,
@@ -193,7 +193,7 @@
                 expressionType is NullType)) {
           // It is a compile-time error if s is `return e;`, T is void, and S is
           // neither void, dynamic, nor Null.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               statement.expression!,
               messageReturnFromVoidFunction,
               statement.expression!.fileOffset,
@@ -203,7 +203,7 @@
             expressionType is VoidType) {
           // It is a compile-time error if s is `return e;`, T is neither void
           // nor dynamic, and S is void.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               statement.expression!,
               templateInvalidReturn.withArguments(expressionType,
                   _declaredReturnType, inferrer.isNonNullableByDefault),
@@ -238,7 +238,7 @@
             returnType is NullType) {
           // Valid return;
         } else {
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               new NullLiteral()..fileOffset = statement.fileOffset,
               messageReturnWithoutExpression,
               statement.fileOffset,
@@ -262,7 +262,7 @@
             expressionType is! DynamicType &&
             expressionType is! NullType) {
           // Invalid if T is void and S is not void, dynamic, or Null
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               statement.expression!,
               messageReturnFromVoidFunction,
               statement.expression!.fileOffset,
@@ -273,7 +273,7 @@
             returnType is! DynamicType &&
             returnType is! NullType) {
           // Invalid if S is void and T is not void, dynamic, or Null.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               statement.expression!,
               messageVoidExpression,
               statement.expression!.fileOffset,
@@ -443,7 +443,7 @@
       Statement resultStatement =
           inferenceResult.hasChanged ? inferenceResult.statement : body;
       // Create a synthetic return statement with the error.
-      Statement returnStatement = new ReturnStatement(inferrer.helper!
+      Statement returnStatement = new ReturnStatement(inferrer.helper
           .wrapInProblem(
               new NullLiteral()..fileOffset = fileOffset,
               templateImplicitReturnNull.withArguments(
@@ -528,7 +528,7 @@
             futureValueType is NullType) {
           // Valid return;
         } else {
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               new NullLiteral()..fileOffset = statement.fileOffset,
               messageReturnWithoutExpressionAsync,
               statement.fileOffset,
@@ -553,7 +553,7 @@
                 flattenedExpressionType is NullType)) {
           // It is a compile-time error if s is `return e;`, T_v is void, and
           // flatten(S) is neither void, dynamic, Null.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               new NullLiteral()..fileOffset = statement.fileOffset,
               templateInvalidReturnAsync.withArguments(
                   expressionType, returnType, inferrer.isNonNullableByDefault),
@@ -565,7 +565,7 @@
             flattenedExpressionType is VoidType) {
           // It is a compile-time error if s is `return e;`, T_v is neither void
           // nor dynamic, and flatten(S) is void.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               new NullLiteral()..fileOffset = statement.fileOffset,
               templateInvalidReturnAsync.withArguments(
                   expressionType, returnType, inferrer.isNonNullableByDefault),
@@ -610,7 +610,7 @@
             flattenedReturnType is NullType) {
           // Valid return;
         } else {
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               new NullLiteral()..fileOffset = statement.fileOffset,
               messageReturnWithoutExpression,
               statement.fileOffset,
@@ -644,7 +644,7 @@
             flattenedExpressionType is! DynamicType &&
             flattenedExpressionType is! NullType) {
           // Invalid if T is void and flatten(S) is not void, dynamic, or Null.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               statement.expression!,
               messageReturnFromVoidFunction,
               statement.expression!.fileOffset,
@@ -656,7 +656,7 @@
             flattenedReturnType is! NullType) {
           // Invalid if flatten(S) is void and flatten(T) is not void, dynamic,
           // or Null.
-          statement.expression = inferrer.helper!.wrapInProblem(
+          statement.expression = inferrer.helper.wrapInProblem(
               statement.expression!,
               messageVoidExpression,
               statement.expression!.fileOffset,
@@ -856,7 +856,7 @@
       Statement resultStatement =
           inferenceResult.hasChanged ? inferenceResult.statement : body;
       // Create a synthetic return statement with the error.
-      Statement returnStatement = new ReturnStatement(inferrer.helper!
+      Statement returnStatement = new ReturnStatement(inferrer.helper
           .wrapInProblem(
               new NullLiteral()..fileOffset = fileOffset,
               templateImplicitReturnNull.withArguments(
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 7381b60..5d50345 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
@@ -173,7 +173,14 @@
 
   AssignedVariables<TreeNode, VariableDeclaration> get assignedVariables;
 
-  InferenceHelper? helper;
+  InferenceHelper get helper;
+
+  void set helper(InferenceHelper helper);
+
+  /// Indicates whether the construct we are currently performing inference for
+  /// is outside of a method body, and hence top level type inference rules
+  /// should apply.
+  bool get isTopLevel;
 
   /// Performs full type inference on the given field initializer.
   ExpressionInferenceResult inferFieldInitializer(
@@ -263,9 +270,7 @@
   @override
   final Uri uriForInstrumentation;
 
-  /// Indicates whether the construct we are currently performing inference for
-  /// is outside of a method body, and hence top level type inference rules
-  /// should apply.
+  @override
   final bool isTopLevel;
 
   final ClassHierarchy classHierarchy;
@@ -280,8 +285,7 @@
   @override
   final SourceLibraryBuilder libraryBuilder;
 
-  @override
-  InferenceHelper? helper;
+  InferenceHelper? _helper;
 
   /// Context information for the current closure, or `null` if we are not
   /// inside a closure.
@@ -304,6 +308,18 @@
         typeSchemaEnvironment = engine.typeSchemaEnvironment,
         isTopLevel = topLevel {}
 
+  @override
+  InferenceHelper get helper => _helper!;
+
+  @override
+  void set helper(InferenceHelper helper) {
+    if (isTopLevel) {
+      throw new StateError("Attempting to assign TypeInferrerImpl.helper "
+          "during top-level inference.");
+    }
+    _helper = helper;
+  }
+
   CoreTypes get coreTypes => engine.coreTypes;
 
   bool get isInferenceUpdate1Enabled =>
@@ -342,8 +358,9 @@
       int fileOffset, Message errorMessage, Message warningMessage) {
     if (libraryBuilder.loader.target.context.options.warnOnReachabilityCheck &&
         // ignore: unnecessary_null_comparison
-        warningMessage != null) {
-      helper?.addProblem(warningMessage, fileOffset, noLength);
+        warningMessage != null &&
+        !isTopLevel) {
+      helper.addProblem(warningMessage, fileOffset, noLength);
     }
     Arguments arguments;
     // ignore: unnecessary_null_comparison
@@ -499,7 +516,7 @@
     } else {
       inferenceResult = initializer.accept(new InferenceVisitor(this));
     }
-    this.helper = null;
+    _helper = null;
     return inferenceResult;
   }
 
@@ -684,13 +701,13 @@
         break;
       case AssignabilityKind.unassignableVoid:
         // Error: not assignable.  Perform error recovery.
-        result = helper!.wrapInProblem(
+        result = helper.wrapInProblem(
             expression, messageVoidExpression, expression.fileOffset, noLength);
         break;
       case AssignabilityKind.unassignablePrecise:
         // The type of the expression is known precisely, so an implicit
         // downcast is guaranteed to fail.  Insert a compile-time error.
-        result = helper!.wrapInProblem(
+        result = helper.wrapInProblem(
             expression,
             preciseTypeErrorTemplate!.withArguments(
                 expressionType, contextType, isNonNullableByDefault),
@@ -751,7 +768,7 @@
         break;
       default:
         return unhandled("${assignabilityResult}", "ensureAssignable",
-            fileOffset, helper!.uri);
+            fileOffset, helper.uri);
     }
 
     if (!identical(result, expression)) {
@@ -778,7 +795,7 @@
       ..isTypeError = true
       ..fileOffset = expression.fileOffset;
     if (contextType is! InvalidType) {
-      errorNode = helper!.wrapInProblem(
+      errorNode = helper.wrapInProblem(
           errorNode,
           template.withArguments(callName.text),
           errorNode.fileOffset,
@@ -803,7 +820,7 @@
       ..isForNonNullableByDefault = isNonNullableByDefault
       ..fileOffset = expression.fileOffset;
     if (contextType is! InvalidType && expressionType is! InvalidType) {
-      errorNode = helper!.wrapInProblem(
+      errorNode = helper.wrapInProblem(
           errorNode, message, errorNode.fileOffset, noLength,
           context: context);
     }
@@ -1385,7 +1402,7 @@
           identical(name.text, unaryMinusName.text)) {
         length = 1;
       }
-      return helper!.buildProblem(
+      return helper.buildProblem(
           errorTemplate.withArguments(name.text,
               resolveTypeParameter(receiverType), isNonNullableByDefault),
           fileOffset,
@@ -2033,7 +2050,7 @@
       {List<LocatedMessage>? context}) {
     return createNullAwareExpressionInferenceResult(
         result.inferredType,
-        helper!.wrapInProblem(
+        helper.wrapInProblem(
             result.nullAwareAction, message, fileOffset, length,
             context: context),
         result.nullAwareGuards);
@@ -2076,7 +2093,8 @@
 
     // For full (non-top level) inference, we need access to the
     // ExpressionGeneratorHelper so that we can perform error recovery.
-    assert(isTopLevel || helper != null);
+    assert(isTopLevel || _helper != null,
+        "Helper hasn't been set up for full inference.");
 
     // When doing top level inference, we skip subexpressions whose type isn't
     // needed so that we don't induce bogus dependencies on fields mentioned in
@@ -2099,8 +2117,8 @@
     assert(inferredType != null,
         "No type inferred for $expression (${expression.runtimeType}).");
     if (inferredType is VoidType && !isVoidAllowed) {
-      if (expression.parent is! ArgumentsImpl) {
-        helper?.addProblem(
+      if (expression.parent is! ArgumentsImpl && !isTopLevel) {
+        helper.addProblem(
             messageVoidExpression, expression.fileOffset, noLength);
       }
     }
@@ -2159,7 +2177,7 @@
         inferExpression(initializer, declaredType, true, isVoidAllowed: true);
     initializerResult = ensureAssignableResult(declaredType, initializerResult,
         isVoidAllowed: declaredType is VoidType);
-    this.helper = null;
+    _helper = null;
     return initializerResult;
   }
 
@@ -2185,7 +2203,7 @@
     assert(!(asyncMarker == AsyncMarker.Async && futureValueType == null),
         "No future value type computed.");
     closureContext = null;
-    this.helper = null;
+    _helper = null;
     flowAnalysis.finish();
     return new InferredFunctionBody(
         result.hasChanged ? result.statement : body, futureValueType);
@@ -2624,7 +2642,7 @@
 
     if (isSpecialCasedBinaryOperator || isSpecialCasedTernaryOperator) {
       if (typeChecksNeeded && !identical(calleeType, unknownFunction)) {
-        LocatedMessage? argMessage = helper!.checkArgumentsForType(
+        LocatedMessage? argMessage = helper.checkArgumentsForType(
             calleeType, arguments, offset,
             isExtensionMemberInvocation: isExtensionMemberInvocation);
         if (argMessage != null) {
@@ -2634,7 +2652,7 @@
               argMessage.messageObject,
               argMessage.charOffset,
               argMessage.length,
-              helper!,
+              helper,
               isInapplicable: true,
               hoistedArguments: localHoistedExpressions);
         }
@@ -2657,23 +2675,8 @@
     }
 
     // Check for and remove duplicated named arguments.
-    List<NamedExpression> named = arguments.named;
-    if (named.length == 2) {
-      if (named[0].name == named[1].name) {
-        String name = named[1].name;
-        Expression error = helper!.wrapInProblem(
-            _createDuplicateExpression(
-                named[0].fileOffset, named[0].value, named[1].value),
-            templateDuplicatedNamedArgument.withArguments(name),
-            named[1].fileOffset,
-            name.length);
-        arguments.named = [new NamedExpression(named[1].name, error)];
-        if (useFormalAndActualTypes) {
-          formalTypes!.removeLast();
-          actualTypes!.removeLast();
-        }
-      }
-    } else if (named.length > 2) {
+    if (!isTopLevel) {
+      List<NamedExpression> named = arguments.named;
       Map<String, NamedExpression> seenNames = <String, NamedExpression>{};
       bool hasProblem = false;
       int namedTypeIndex = arguments.positional.length;
@@ -2683,7 +2686,7 @@
         if (seenNames.containsKey(name)) {
           hasProblem = true;
           NamedExpression prevNamedExpression = seenNames[name]!;
-          prevNamedExpression.value = helper!.wrapInProblem(
+          prevNamedExpression.value = helper.wrapInProblem(
               _createDuplicateExpression(prevNamedExpression.fileOffset,
                   prevNamedExpression.value, expression.value),
               templateDuplicatedNamedArgument.withArguments(name),
@@ -2727,7 +2730,7 @@
     List<DartType> positionalArgumentTypes = [];
     List<NamedType> namedArgumentTypes = [];
     if (typeChecksNeeded && !identical(calleeType, unknownFunction)) {
-      LocatedMessage? argMessage = helper!.checkArgumentsForType(
+      LocatedMessage? argMessage = helper.checkArgumentsForType(
           calleeType, arguments, offset,
           isExtensionMemberInvocation: isExtensionMemberInvocation);
       if (argMessage != null) {
@@ -2737,7 +2740,7 @@
             argMessage.messageObject,
             argMessage.charOffset,
             argMessage.length,
-            helper!,
+            helper,
             isInapplicable: true,
             hoistedArguments: localHoistedExpressions);
       } else {
@@ -3015,9 +3018,12 @@
   void inferMetadata(
       InferenceHelper helper, TreeNode? parent, List<Expression>? annotations) {
     if (annotations != null) {
-      this.helper = helper;
+      // We bypass the check for assignment of the helper during top-level
+      // inference and use `_helper = helper` instead of `this.helper = helper`
+      // because inference on metadata requires the helper.
+      _helper = helper;
       inferMetadataKeepingHelper(parent, annotations);
-      this.helper = null;
+      _helper = null;
     }
   }
 
@@ -3205,11 +3211,8 @@
           isImplicitCall: isImplicitCall,
           isExtensionMemberInvocation: true);
       if (!isTopLevel) {
-        libraryBuilder.checkBoundsInStaticInvocation(
-            staticInvocation,
-            typeSchemaEnvironment,
-            helper!.uri,
-            getTypeArgumentsInfo(arguments));
+        libraryBuilder.checkBoundsInStaticInvocation(staticInvocation,
+            typeSchemaEnvironment, helper.uri, getTypeArgumentsInfo(arguments));
       }
 
       Expression replacement = result.applyResult(staticInvocation);
@@ -3226,7 +3229,7 @@
           //   extension on int {
           //     void call() {}
           //   }
-          replacement = helper!.wrapInProblem(
+          replacement = helper.wrapInProblem(
               replacement,
               templateNullableExpressionCallError.withArguments(
                   receiverType, isNonNullableByDefault),
@@ -3241,7 +3244,7 @@
           //   extension on int {
           //     void methodOnNonNullInt() {}
           //   }
-          replacement = helper!.wrapInProblem(
+          replacement = helper.wrapInProblem(
               replacement,
               templateNullableMethodCallError.withArguments(
                   name.text, receiverType, isNonNullableByDefault),
@@ -3323,7 +3326,7 @@
         // Handles cases like:
         //   void Function()? f;
         //   f();
-        replacement = helper!.wrapInProblem(
+        replacement = helper.wrapInProblem(
             replacement,
             templateNullableExpressionCallError.withArguments(
                 receiverType, isNonNullableByDefault),
@@ -3334,7 +3337,7 @@
         // Handles cases like:
         //   void Function()? f;
         //   f.call();
-        replacement = helper!.wrapInProblem(
+        replacement = helper.wrapInProblem(
             replacement,
             templateNullableMethodCallError.withArguments(
                 callName.text, receiverType, isNonNullableByDefault),
@@ -3499,7 +3502,7 @@
         //   class C {
         //     void call();
         //   }
-        replacement = helper!.wrapInProblem(
+        replacement = helper.wrapInProblem(
             replacement,
             templateNullableExpressionCallError.withArguments(
                 receiverType, isNonNullableByDefault),
@@ -3510,7 +3513,7 @@
         // Handles cases like:
         //   int? i;
         //   i.abs();
-        replacement = helper!.wrapInProblem(
+        replacement = helper.wrapInProblem(
             replacement,
             templateNullableMethodCallError.withArguments(
                 methodName.text, receiverType, isNonNullableByDefault),
@@ -3624,7 +3627,7 @@
             new ExpressionInvocation(receiver, arguments)
               ..fileOffset = fileOffset);
       } else {
-        Expression error = helper!.buildProblem(
+        Expression error = helper.buildProblem(
             templateImplicitCallOfNonMethod.withArguments(
                 receiverType, isNonNullableByDefault),
             fileOffset,
@@ -3821,7 +3824,7 @@
             new ExpressionInvocation(receiver, arguments)
               ..fileOffset = fileOffset);
       } else {
-        Expression error = helper!.buildProblem(
+        Expression error = helper.buildProblem(
             templateImplicitCallOfNonMethod.withArguments(
                 receiverType, isNonNullableByDefault),
             fileOffset,
@@ -4070,7 +4073,7 @@
           actualMethodName,
           interfaceTarget,
           arguments,
-          helper!.uri,
+          helper.uri,
           fileOffset);
     }
   }
@@ -4083,14 +4086,8 @@
     // If [arguments] were inferred, check them.
     if (!isTopLevel) {
       // We only perform checks in full inference.
-      libraryBuilder.checkBoundsInInstantiation(
-          typeSchemaEnvironment,
-          classHierarchy,
-          this,
-          functionType,
-          arguments,
-          helper!.uri,
-          fileOffset,
+      libraryBuilder.checkBoundsInInstantiation(typeSchemaEnvironment,
+          classHierarchy, this, functionType, arguments, helper.uri, fileOffset,
           inferred: inferred);
     }
   }
@@ -4107,7 +4104,7 @@
           functionType,
           localName,
           arguments,
-          helper!.uri,
+          helper.uri,
           fileOffset);
     }
   }
@@ -4197,7 +4194,7 @@
     if (hasDeclaredInitializer) {
       initializer = ensureAssignableResult(declaredType, result).expression;
     }
-    this.helper = null;
+    _helper = null;
     return initializer;
   }
 
@@ -4231,7 +4228,6 @@
 
     // For full (non-top level) inference, we need access to the
     // ExpressionGeneratorHelper so that we can perform error recovery.
-    if (!isTopLevel) assert(helper != null);
     InferenceVisitor visitor = new InferenceVisitor(this);
     if (statement is InternalStatement) {
       return statement.acceptInference(visitor);
@@ -4491,7 +4487,7 @@
               templateDuplicatedDeclarationUse.withArguments(name.text),
               charOffset,
               name.text.length,
-              helper!.uri);
+              helper.uri);
         }
         classMember = null;
       }
@@ -4576,7 +4572,7 @@
       return engine.forest.createSuperMethodInvocation(fileOffset, indexGetName,
           null, engine.forest.createArguments(fileOffset, <Expression>[index]));
     } else {
-      return helper!.buildProblem(
+      return helper.buildProblem(
           templateSuperclassHasNoMethod.withArguments(indexGetName.text),
           fileOffset,
           noLength);
@@ -4593,7 +4589,7 @@
           engine.forest
               .createArguments(fileOffset, <Expression>[index, value]));
     } else {
-      return helper!.buildProblem(
+      return helper.buildProblem(
           templateSuperclassHasNoMethod.withArguments(indexSetName.text),
           fileOffset,
           noLength);
@@ -4670,7 +4666,7 @@
           .toList();
       template = ambiguousTemplate;
     }
-    return helper!.wrapInProblem(
+    return helper.wrapInProblem(
         wrappedExpression,
         template.withArguments(name.text, resolveTypeParameter(receiverType),
             isNonNullableByDefault),
@@ -4691,7 +4687,7 @@
           .createMethodInvocation(fileOffset, receiver, name, arguments);
     } else if (implicitInvocationPropertyName != null) {
       assert(extensionAccessCandidates == null);
-      return helper!.wrapInProblem(
+      return helper.wrapInProblem(
           _createInvalidInvocation(fileOffset, receiver, name, arguments),
           templateInvokeNonFunction
               .withArguments(implicitInvocationPropertyName.text),
@@ -4891,7 +4887,7 @@
               typeArgument, isNonNullableByDefault),
           fileOffset,
           noLength,
-          helper!.uri);
+          helper.uri);
     }
   }
 
@@ -4918,6 +4914,9 @@
             thisType, library, assignedVariables, dataForTesting);
 
   @override
+  bool get isTopLevel => impl.isTopLevel;
+
+  @override
   AssignedVariables<TreeNode, VariableDeclaration> get assignedVariables =>
       impl.assignedVariables;
 
@@ -5056,10 +5055,10 @@
   }
 
   @override
-  InferenceHelper? get helper => impl.helper;
+  InferenceHelper get helper => impl.helper;
 
   @override
-  void set helper(InferenceHelper? helper) => impl.helper = helper;
+  void set helper(InferenceHelper helper) => impl.helper = helper;
 }
 
 abstract class MixinInferrer {
@@ -6015,7 +6014,7 @@
     int offset = node.fileOffset;
     return templateVariableCouldBeNullDueToWrite
         .withArguments(reason.variable.name!, reason.documentationLink)
-        .withLocation(inferrer.helper!.uri, offset, noLength);
+        .withLocation(inferrer.helper.uri, offset, noLength);
   }
 
   @override
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 2ed7f4c..0874509 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -852,7 +852,8 @@
               NonNullableByDefaultCompiledMode.Invalid) {
             // In this case we expect and want a runtime error.
             if (runResult.outcome == ExpectationSet.Default["RuntimeError"]) {
-              // We convert this to pass because that's exactly what we'd expect.
+              // We convert this to pass because that's exactly what we'd
+              // expect.
               return pass(result);
             } else {
               // Different outcome - that's a failure!
diff --git a/pkg/front_end/testcases/general/issue49153.dart b/pkg/front_end/testcases/general/issue49153.dart
new file mode 100644
index 0000000..b30cf16
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X extends num> {
+  const A({int? x, String? y, bool? z});
+}
+
+const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49153.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49153.dart.textual_outline.expect
new file mode 100644
index 0000000..92e696b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A<X extends num> {
+  const A({int? x, String? y, bool? z});
+}
+
+const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49153.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49153.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..92e696b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A<X extends num> {
+  const A({int? x, String? y, bool? z});
+}
+
+const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49153.dart.weak.expect b/pkg/front_end/testcases/general/issue49153.dart.weak.expect
new file mode 100644
index 0000000..9a98680
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+// const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+//                                          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num> extends core::Object /*hasConstConstructor*/  {
+  const constructor •({core::int? x = #C1, core::String? y = #C1, core::bool? z = #C1}) → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static const field core::Map<core::String, self::A<core::num>> a = invalid-expression "pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+const a = {\"a\": A(x: 0, y: \"\", z: false, x: 1)};
+                                         ^";
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49153.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49153.dart.weak.modular.expect
new file mode 100644
index 0000000..9a98680
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart.weak.modular.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+// const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+//                                          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num> extends core::Object /*hasConstConstructor*/  {
+  const constructor •({core::int? x = #C1, core::String? y = #C1, core::bool? z = #C1}) → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static const field core::Map<core::String, self::A<core::num>> a = invalid-expression "pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+const a = {\"a\": A(x: 0, y: \"\", z: false, x: 1)};
+                                         ^";
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49153.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49153.dart.weak.outline.expect
new file mode 100644
index 0000000..bac553f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+// const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+//                                          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num> extends core::Object /*hasConstConstructor*/  {
+  const constructor •({core::int? x = null, core::String? y = null, core::bool? z = null}) → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static const field core::Map<core::String, self::A<core::num>> a = const <core::String, self::A<core::num>>{"a": const self::A::•<core::num>(x: invalid-expression "pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+const a = {\"a\": A(x: 0, y: \"\", z: false, x: 1)};
+                                         ^" in block {
+  0;
+} =>1, y: "", z: false)};
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue49153.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49153.dart.weak.transformed.expect
new file mode 100644
index 0000000..9a98680
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49153.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+// const a = {"a": A(x: 0, y: "", z: false, x: 1)};
+//                                          ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num> extends core::Object /*hasConstConstructor*/  {
+  const constructor •({core::int? x = #C1, core::String? y = #C1, core::bool? z = #C1}) → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+static const field core::Map<core::String, self::A<core::num>> a = invalid-expression "pkg/front_end/testcases/general/issue49153.dart:9:42: Error: Duplicated named argument 'x'.
+const a = {\"a\": A(x: 0, y: \"\", z: false, x: 1)};
+                                         ^";
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/issue49206.dart b/pkg/front_end/testcases/general/issue49206.dart
new file mode 100644
index 0000000..f8b0b8a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {}
+
+fn1<T>() => const <A<T>>[];
+fn2<T>() => const <A<T>>{};
+fn3<T>() => const <A<T>, String>{};
+fn4<T>() => const <int, A<T>>{};
+fn5<T>() => const <A<T>, A<T>>{};
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49206.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue49206.dart.textual_outline.expect
new file mode 100644
index 0000000..a36c769
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+fn1<T>() => const <A<T>>[];
+fn2<T>() => const <A<T>>{};
+fn3<T>() => const <A<T>, String>{};
+fn4<T>() => const <int, A<T>>{};
+fn5<T>() => const <A<T>, A<T>>{};
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49206.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue49206.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a36c769
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+fn1<T>() => const <A<T>>[];
+fn2<T>() => const <A<T>>{};
+fn3<T>() => const <A<T>, String>{};
+fn4<T>() => const <int, A<T>>{};
+fn5<T>() => const <A<T>, A<T>>{};
+main() {}
diff --git a/pkg/front_end/testcases/general/issue49206.dart.weak.expect b/pkg/front_end/testcases/general/issue49206.dart.weak.expect
new file mode 100644
index 0000000..daef32e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart.weak.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49206.dart:7:13: Error: Type variables can't be used as constants.
+// fn1<T>() => const <A<T>>[];
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:8:13: Error: Type variables can't be used as constants.
+// fn2<T>() => const <A<T>>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:9:13: Error: Type variables can't be used as constants.
+// fn3<T>() => const <A<T>, String>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:10:13: Error: Type variables can't be used as constants.
+// fn4<T>() => const <int, A<T>>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:11:13: Error: Type variables can't be used as constants.
+// fn5<T>() => const <A<T>, A<T>>{};
+//             ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method fn1<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn2<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn3<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn4<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn5<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49206.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue49206.dart.weak.modular.expect
new file mode 100644
index 0000000..daef32e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart.weak.modular.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49206.dart:7:13: Error: Type variables can't be used as constants.
+// fn1<T>() => const <A<T>>[];
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:8:13: Error: Type variables can't be used as constants.
+// fn2<T>() => const <A<T>>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:9:13: Error: Type variables can't be used as constants.
+// fn3<T>() => const <A<T>, String>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:10:13: Error: Type variables can't be used as constants.
+// fn4<T>() => const <int, A<T>>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:11:13: Error: Type variables can't be used as constants.
+// fn5<T>() => const <A<T>, A<T>>{};
+//             ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method fn1<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn2<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn3<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn4<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn5<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue49206.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue49206.dart.weak.outline.expect
new file mode 100644
index 0000000..e3b23b4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    ;
+}
+static method fn1<T extends core::Object? = dynamic>() → dynamic
+  ;
+static method fn2<T extends core::Object? = dynamic>() → dynamic
+  ;
+static method fn3<T extends core::Object? = dynamic>() → dynamic
+  ;
+static method fn4<T extends core::Object? = dynamic>() → dynamic
+  ;
+static method fn5<T extends core::Object? = dynamic>() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue49206.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue49206.dart.weak.transformed.expect
new file mode 100644
index 0000000..daef32e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue49206.dart.weak.transformed.expect
@@ -0,0 +1,43 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue49206.dart:7:13: Error: Type variables can't be used as constants.
+// fn1<T>() => const <A<T>>[];
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:8:13: Error: Type variables can't be used as constants.
+// fn2<T>() => const <A<T>>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:9:13: Error: Type variables can't be used as constants.
+// fn3<T>() => const <A<T>, String>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:10:13: Error: Type variables can't be used as constants.
+// fn4<T>() => const <int, A<T>>{};
+//             ^
+//
+// pkg/front_end/testcases/general/issue49206.dart:11:13: Error: Type variables can't be used as constants.
+// fn5<T>() => const <A<T>, A<T>>{};
+//             ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::T%>
+    : super core::Object::•()
+    ;
+}
+static method fn1<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn2<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn3<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn4<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method fn5<T extends core::Object? = dynamic>() → dynamic
+  return invalid-expression "Type variables can't be used as constants.";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
index 0524cac..ed2219b 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
@@ -170,8 +170,8 @@
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> SymbolConstant(#noFolding)
 Evaluated: ListLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> ListConstant(const <Type*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> SymbolConstant(#clear)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:564:8 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> SymbolConstant(#clear)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:676:8 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 268, effectively constant: 91
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index e10c97c..6ea7e64 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -384,10 +384,110 @@
   static const warningHeader = "warning";
   static const wwwAuthenticateHeader = "www-authenticate";
 
+  @Deprecated("Use acceptHeader instead")
+  static const ACCEPT = acceptHeader;
+  @Deprecated("Use acceptCharsetHeader instead")
+  static const ACCEPT_CHARSET = acceptCharsetHeader;
+  @Deprecated("Use acceptEncodingHeader instead")
+  static const ACCEPT_ENCODING = acceptEncodingHeader;
+  @Deprecated("Use acceptLanguageHeader instead")
+  static const ACCEPT_LANGUAGE = acceptLanguageHeader;
+  @Deprecated("Use acceptRangesHeader instead")
+  static const ACCEPT_RANGES = acceptRangesHeader;
+  @Deprecated("Use ageHeader instead")
+  static const AGE = ageHeader;
+  @Deprecated("Use allowHeader instead")
+  static const ALLOW = allowHeader;
+  @Deprecated("Use authorizationHeader instead")
+  static const AUTHORIZATION = authorizationHeader;
+  @Deprecated("Use cacheControlHeader instead")
+  static const CACHE_CONTROL = cacheControlHeader;
+  @Deprecated("Use connectionHeader instead")
+  static const CONNECTION = connectionHeader;
+  @Deprecated("Use contentEncodingHeader instead")
+  static const CONTENT_ENCODING = contentEncodingHeader;
+  @Deprecated("Use contentLanguageHeader instead")
+  static const CONTENT_LANGUAGE = contentLanguageHeader;
+  @Deprecated("Use contentLengthHeader instead")
+  static const CONTENT_LENGTH = contentLengthHeader;
+  @Deprecated("Use contentLocationHeader instead")
+  static const CONTENT_LOCATION = contentLocationHeader;
+  @Deprecated("Use contentMD5Header instead")
+  static const CONTENT_MD5 = contentMD5Header;
+  @Deprecated("Use contentRangeHeader instead")
+  static const CONTENT_RANGE = contentRangeHeader;
+  @Deprecated("Use contentTypeHeader instead")
+  static const CONTENT_TYPE = contentTypeHeader;
+  @Deprecated("Use dateHeader instead")
+  static const DATE = dateHeader;
+  @Deprecated("Use etagHeader instead")
+  static const ETAG = etagHeader;
+  @Deprecated("Use expectHeader instead")
+  static const EXPECT = expectHeader;
+  @Deprecated("Use expiresHeader instead")
+  static const EXPIRES = expiresHeader;
+  @Deprecated("Use fromHeader instead")
+  static const FROM = fromHeader;
+  @Deprecated("Use hostHeader instead")
+  static const HOST = hostHeader;
+  @Deprecated("Use ifMatchHeader instead")
+  static const IF_MATCH = ifMatchHeader;
+  @Deprecated("Use ifModifiedSinceHeader instead")
+  static const IF_MODIFIED_SINCE = ifModifiedSinceHeader;
+  @Deprecated("Use ifNoneMatchHeader instead")
+  static const IF_NONE_MATCH = ifNoneMatchHeader;
+  @Deprecated("Use ifRangeHeader instead")
+  static const IF_RANGE = ifRangeHeader;
+  @Deprecated("Use ifUnmodifiedSinceHeader instead")
+  static const IF_UNMODIFIED_SINCE = ifUnmodifiedSinceHeader;
+  @Deprecated("Use lastModifiedHeader instead")
+  static const LAST_MODIFIED = lastModifiedHeader;
+  @Deprecated("Use locationHeader instead")
+  static const LOCATION = locationHeader;
+  @Deprecated("Use maxForwardsHeader instead")
+  static const MAX_FORWARDS = maxForwardsHeader;
+  @Deprecated("Use pragmaHeader instead")
+  static const PRAGMA = pragmaHeader;
+  @Deprecated("Use proxyAuthenticateHeader instead")
+  static const PROXY_AUTHENTICATE = proxyAuthenticateHeader;
+  @Deprecated("Use proxyAuthorizationHeader instead")
+  static const PROXY_AUTHORIZATION = proxyAuthorizationHeader;
+  @Deprecated("Use rangeHeader instead")
+  static const RANGE = rangeHeader;
+  @Deprecated("Use refererHeader instead")
+  static const REFERER = refererHeader;
+  @Deprecated("Use retryAfterHeader instead")
+  static const RETRY_AFTER = retryAfterHeader;
+  @Deprecated("Use serverHeader instead")
+  static const SERVER = serverHeader;
+  @Deprecated("Use teHeader instead")
+  static const TE = teHeader;
+  @Deprecated("Use trailerHeader instead")
+  static const TRAILER = trailerHeader;
+  @Deprecated("Use transferEncodingHeader instead")
+  static const TRANSFER_ENCODING = transferEncodingHeader;
+  @Deprecated("Use upgradeHeader instead")
+  static const UPGRADE = upgradeHeader;
+  @Deprecated("Use userAgentHeader instead")
+  static const USER_AGENT = userAgentHeader;
+  @Deprecated("Use varyHeader instead")
+  static const VARY = varyHeader;
+  @Deprecated("Use viaHeader instead")
+  static const VIA = viaHeader;
+  @Deprecated("Use warningHeader instead")
+  static const WARNING = warningHeader;
+  @Deprecated("Use wwwAuthenticateHeader instead")
+  static const WWW_AUTHENTICATE = wwwAuthenticateHeader;
+
   // Cookie headers from RFC 6265.
   static const cookieHeader = "cookie";
   static const setCookieHeader = "set-cookie";
 
+  @Deprecated("Use cookieHeader instead")
+  static const COOKIE = cookieHeader;
+  @Deprecated("Use setCookieHeader instead")
+  static const SET_COOKIE = setCookieHeader;
+
   // TODO(39783): Document this.
   static const generalHeaders = [
     cacheControlHeader,
@@ -401,6 +501,9 @@
     warningHeader
   ];
 
+  @Deprecated("Use generalHeaders instead")
+  static const GENERAL_HEADERS = generalHeaders;
+
   static const entityHeaders = [
     allowHeader,
     contentEncodingHeader,
@@ -414,6 +517,9 @@
     lastModifiedHeader
   ];
 
+  @Deprecated("Use entityHeaders instead")
+  static const ENTITY_HEADERS = entityHeaders;
+
   static const responseHeaders = [
     acceptRangesHeader,
     ageHeader,
@@ -426,6 +532,9 @@
     wwwAuthenticateHeader
   ];
 
+  @Deprecated("Use responseHeaders instead")
+  static const RESPONSE_HEADERS = responseHeaders;
+
   static const requestHeaders = [
     acceptHeader,
     acceptCharsetHeader,
@@ -448,6 +557,9 @@
     userAgentHeader
   ];
 
+  @Deprecated("Use requestHeaders instead")
+  static const REQUEST_HEADERS = requestHeaders;
+
   /// The date specified by the [dateHeader] header, if any.
   DateTime? date;
 
@@ -661,21 +773,29 @@
   ///
   ///     text/plain; charset=utf-8
   static final text = ContentType("text", "plain", charset: "utf-8");
+  @Deprecated("Use text instead")
+  static final TEXT = text;
 
   /// Content type for HTML using UTF-8 encoding.
   ///
   ///    text/html; charset=utf-8
   static final html = ContentType("text", "html", charset: "utf-8");
+  @Deprecated("Use html instead")
+  static final HTML = html;
 
   /// Content type for JSON using UTF-8 encoding.
   ///
   ///    application/json; charset=utf-8
   static final json = ContentType("application", "json", charset: "utf-8");
+  @Deprecated("Use json instead")
+  static final JSON = json;
 
   /// Content type for binary data.
   ///
   ///    application/octet-stream
   static final binary = ContentType("application", "octet-stream");
+  @Deprecated("Use binary instead")
+  static final BINARY = binary;
 
   /// Creates a new content type object setting the primary type and
   /// sub type. The charset and additional parameters can also be set
@@ -1142,8 +1262,12 @@
 ///     client.findProxy = null;
 abstract class HttpClient {
   static const int defaultHttpPort = 80;
+  @Deprecated("Use defaultHttpPort instead")
+  static const int DEFAULT_HTTP_PORT = defaultHttpPort;
 
   static const int defaultHttpsPort = 443;
+  @Deprecated("Use defaultHttpsPort instead")
+  static const int DEFAULT_HTTPS_PORT = defaultHttpsPort;
 
   /// Enable logging of HTTP requests from all [HttpClient]s to the developer
   /// timeline.
diff --git a/sdk/lib/_http/websocket.dart b/sdk/lib/_http/websocket.dart
index a01823c..9503ae3 100644
--- a/sdk/lib/_http/websocket.dart
+++ b/sdk/lib/_http/websocket.dart
@@ -19,6 +19,33 @@
   static const int missingMandatoryExtension = 1010;
   static const int internalServerError = 1011;
   static const int reserved1015 = 1015;
+
+  @Deprecated("Use normalClosure instead")
+  static const int NORMAL_CLOSURE = normalClosure;
+  @Deprecated("Use goingAway instead")
+  static const int GOING_AWAY = goingAway;
+  @Deprecated("Use protocolError instead")
+  static const int PROTOCOL_ERROR = protocolError;
+  @Deprecated("Use unsupportedData instead")
+  static const int UNSUPPORTED_DATA = unsupportedData;
+  @Deprecated("Use reserved1004 instead")
+  static const int RESERVED_1004 = reserved1004;
+  @Deprecated("Use noStatusReceived instead")
+  static const int NO_STATUS_RECEIVED = noStatusReceived;
+  @Deprecated("Use abnormalClosure instead")
+  static const int ABNORMAL_CLOSURE = abnormalClosure;
+  @Deprecated("Use invalidFramePayloadData instead")
+  static const int INVALID_FRAME_PAYLOAD_DATA = invalidFramePayloadData;
+  @Deprecated("Use policyViolation instead")
+  static const int POLICY_VIOLATION = policyViolation;
+  @Deprecated("Use messageTooBig instead")
+  static const int MESSAGE_TOO_BIG = messageTooBig;
+  @Deprecated("Use missingMandatoryExtension instead")
+  static const int MISSING_MANDATORY_EXTENSION = missingMandatoryExtension;
+  @Deprecated("Use internalServerError instead")
+  static const int INTERNAL_SERVER_ERROR = internalServerError;
+  @Deprecated("Use reserved1015 instead")
+  static const int RESERVED_1015 = reserved1015;
 }
 
 /// Options controlling compression in a [WebSocket].
@@ -41,6 +68,8 @@
   /// * `clientMaxWindowBits`: null (default maximal window size of 15 bits)
   /// * `serverMaxWindowBits`: null (default maximal window size of 15 bits)
   static const CompressionOptions compressionDefault = CompressionOptions();
+  @Deprecated("Use compressionDefault instead")
+  static const CompressionOptions DEFAULT = compressionDefault;
 
   /// No-compression configuration.
   ///
@@ -48,6 +77,8 @@
   /// [WebSocket].
   static const CompressionOptions compressionOff =
       CompressionOptions(enabled: false);
+  @Deprecated("Use compressionOff instead")
+  static const CompressionOptions OFF = compressionOff;
 
   /// Whether the client will reuse its compression instances.
   final bool clientNoContextTakeover;
@@ -269,6 +300,15 @@
   static const int closing = 2;
   static const int closed = 3;
 
+  @Deprecated("Use connecting instead")
+  static const int CONNECTING = connecting;
+  @Deprecated("Use open instead")
+  static const int OPEN = open;
+  @Deprecated("Use closing instead")
+  static const int CLOSING = closing;
+  @Deprecated("Use closed instead")
+  static const int CLOSED = closed;
+
   /// The interval between ping signals.
   ///
   /// A ping message is sent every [pingInterval], starting at the first
diff --git a/tools/VERSION b/tools/VERSION
index b52bd2e..af09950 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 171
+PRERELEASE 172
 PRERELEASE_PATCH 0
\ No newline at end of file